diff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c
index 8449db3..76ec856 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.c
@@ -303,6 +303,43 @@ int32_t	ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt)
 }
 
 /*
+ * Allocate the flow database entry
+ *
+ * ulp_ctxt [in] Ptr to ulp_context
+ * tbl_idx [in] Specify it is regular or default flow
+ * fid [out] The index to the flow entry
+ *
+ * returns 0 on success and negative on failure.
+ */
+int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context		*ulp_ctxt,
+			      enum bnxt_ulp_flow_db_tables	tbl_idx,
+			      uint32_t				*fid)
+{
+	struct bnxt_ulp_flow_db		*flow_db;
+	struct bnxt_ulp_flow_tbl	*flow_tbl;
+
+	*fid = 0; /* Initialize fid to invalid value */
+	flow_db = bnxt_ulp_cntxt_ptr2_flow_db_get(ulp_ctxt);
+	if (!flow_db) {
+		BNXT_TF_DBG(ERR, "Invalid Arguments\n");
+		return -EINVAL;
+	}
+
+	flow_tbl = &flow_db->flow_tbl[tbl_idx];
+	/* check for max flows */
+	if (flow_tbl->num_flows <= flow_tbl->head_index) {
+		BNXT_TF_DBG(ERR, "Flow database has reached max flows\n");
+		return -ENOMEM;
+	}
+	*fid = flow_tbl->flow_tbl_stack[flow_tbl->head_index];
+	flow_tbl->head_index++;
+	ulp_flow_db_active_flow_set(flow_tbl, *fid, 1);
+
+	/* all good, return success */
+	return 0;
+}
+
+/*
  * Allocate the flow database entry.
  * The params->critical_resource has to be set to 0 to allocate a new resource.
  *
diff --git a/drivers/net/bnxt/tf_ulp/ulp_flow_db.h b/drivers/net/bnxt/tf_ulp/ulp_flow_db.h
index 20109b9..eb5effa 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_flow_db.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_flow_db.h
@@ -84,6 +84,19 @@ int32_t	ulp_flow_db_init(struct bnxt_ulp_context *ulp_ctxt);
 int32_t	ulp_flow_db_deinit(struct bnxt_ulp_context *ulp_ctxt);
 
 /*
+ * Allocate the flow database entry
+ *
+ * ulp_ctxt [in] Ptr to ulp_context
+ * tbl_idx [in] Specify it is regular or default flow
+ * fid [out] The index to the flow entry
+ *
+ * returns 0 on success and negative on failure.
+ */
+int32_t ulp_flow_db_fid_alloc(struct bnxt_ulp_context		*ulp_ctxt,
+			      enum bnxt_ulp_flow_db_tables	tbl_idx,
+			      uint32_t				*fid);
+
+/*
  * Allocate the flow database entry.
  * The params->critical_resource has to be set to 0 to allocate a new resource.
  *
diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
index 1b22720..f697f2f 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
@@ -16,12 +16,6 @@
 #include "ulp_flow_db.h"
 #include "ulp_mapper.h"
 
-int32_t
-ulp_mapper_action_tbls_process(struct bnxt_ulp_mapper_parms *parms);
-
-int32_t
-ulp_mapper_class_tbls_process(struct bnxt_ulp_mapper_parms *parms);
-
 /*
  * Get the size of the action property for a given index.
  *
@@ -38,7 +32,76 @@ ulp_mapper_act_prop_size_get(uint32_t idx)
 }
 
 /*
- * Get the list of result fields that implement the flow action
+ * Get the list of result fields that implement the flow action.
+ * Gets a device dependent list of tables that implement the action template id.
+ *
+ * dev_id [in] The device id of the forwarding element
+ *
+ * tid [in] The action template id that matches the flow
+ *
+ * num_tbls [out] The number of action tables in the returned array
+ *
+ * Returns An array of action tables to implement the flow, or NULL on error.
+ */
+static struct bnxt_ulp_mapper_act_tbl_info *
+ulp_mapper_action_tbl_list_get(uint32_t dev_id,
+			       uint32_t tid,
+			       uint32_t *num_tbls)
+{
+	uint32_t	idx;
+	uint32_t	tidx;
+
+	if (!num_tbls) {
+		BNXT_TF_DBG(ERR, "Invalid arguments\n");
+		return NULL;
+	}
+
+	/* template shift and device mask */
+	tidx = ULP_DEVICE_PARAMS_INDEX(tid, dev_id);
+
+	/* NOTE: Need to have something from template compiler to help validate
+	 * range of dev_id and act_tid
+	 */
+	idx		= ulp_act_tmpl_list[tidx].start_tbl_idx;
+	*num_tbls	= ulp_act_tmpl_list[tidx].num_tbls;
+
+	return &ulp_act_tbl_list[idx];
+}
+
+/** Get a list of classifier tables that implement the flow
+ * Gets a device dependent list of tables that implement the class template id
+ *
+ * dev_id [in] The device id of the forwarding element
+ *
+ * tid [in] The template id that matches the flow
+ *
+ * num_tbls [out] The number of classifier tables in the returned array
+ *
+ * returns An array of classifier tables to implement the flow, or NULL on
+ * error
+ */
+static struct bnxt_ulp_mapper_class_tbl_info *
+ulp_mapper_class_tbl_list_get(uint32_t dev_id,
+			      uint32_t tid,
+			      uint32_t *num_tbls)
+{
+	uint32_t idx;
+	uint32_t tidx = ULP_DEVICE_PARAMS_INDEX(tid, dev_id);
+
+	if (!num_tbls)
+		return NULL;
+
+	/* NOTE: Need to have something from template compiler to help validate
+	 * range of dev_id and tid
+	 */
+	idx		= ulp_class_tmpl_list[tidx].start_tbl_idx;
+	*num_tbls	= ulp_class_tmpl_list[tidx].num_tbls;
+
+	return &ulp_class_tbl_list[idx];
+}
+
+/*
+ * Get the list of key fields that implement the flow.
  *
  * ctxt [in] The ulp context
  *
@@ -46,7 +109,7 @@ ulp_mapper_act_prop_size_get(uint32_t idx)
  *
  * num_flds [out] The number of key fields in the returned array
  *
- * returns array of Key fields, or NULL on error
+ * Returns array of Key fields, or NULL on error.
  */
 static struct bnxt_ulp_mapper_class_key_field_info *
 ulp_mapper_key_fields_get(struct bnxt_ulp_mapper_class_tbl_info *tbl,
@@ -1147,7 +1210,7 @@ ulp_mapper_index_tbl_process(struct bnxt_ulp_mapper_parms *parms,
  * Function to process the action template. Iterate through the list
  * action info templates and process it.
  */
-int32_t
+static int32_t
 ulp_mapper_action_tbls_process(struct bnxt_ulp_mapper_parms *parms)
 {
 	uint32_t	i;
@@ -1169,7 +1232,7 @@ ulp_mapper_action_tbls_process(struct bnxt_ulp_mapper_parms *parms)
 }
 
 /* Create the classifier table entries for a flow. */
-int32_t
+static int32_t
 ulp_mapper_class_tbls_process(struct bnxt_ulp_mapper_parms *parms)
 {
 	uint32_t	i;
@@ -1324,3 +1387,116 @@ ulp_mapper_flow_destroy(struct bnxt_ulp_context	*ulp_ctx, uint32_t fid)
 					 fid,
 					 BNXT_ULP_REGULAR_FLOW_TABLE);
 }
+
+/* Function to handle the mapping of the Flow to be compatible
+ * with the underlying hardware.
+ */
+int32_t
+ulp_mapper_flow_create(struct bnxt_ulp_context *ulp_ctx,
+		       uint32_t app_priority __rte_unused,
+		       struct ulp_rte_hdr_bitmap *hdr_bitmap __rte_unused,
+		       struct ulp_rte_hdr_field *hdr_field,
+		       struct ulp_rte_act_bitmap *act_bitmap,
+		       struct ulp_rte_act_prop *act_prop,
+		       uint32_t class_tid,
+		       uint32_t act_tid,
+		       uint32_t *flow_id)
+{
+	struct ulp_regfile		regfile;
+	struct bnxt_ulp_mapper_parms	parms;
+	struct bnxt_ulp_device_params	*device_params;
+	int32_t				rc, trc;
+
+	/* Initialize the parms structure */
+	memset(&parms, 0, sizeof(parms));
+	parms.act_prop = act_prop;
+	parms.act_bitmap = act_bitmap;
+	parms.regfile = &regfile;
+	parms.hdr_field = hdr_field;
+	parms.tfp = bnxt_ulp_cntxt_tfp_get(ulp_ctx);
+	parms.ulp_ctx = ulp_ctx;
+
+	/* Get the device id from the ulp context */
+	if (bnxt_ulp_cntxt_dev_id_get(ulp_ctx, &parms.dev_id)) {
+		BNXT_TF_DBG(ERR, "Invalid ulp context\n");
+		return -EINVAL;
+	}
+
+	/* Get the action table entry from device id and act context id */
+	parms.act_tid = act_tid;
+	parms.atbls = ulp_mapper_action_tbl_list_get(parms.dev_id,
+						     parms.act_tid,
+						     &parms.num_atbls);
+	if (!parms.atbls || !parms.num_atbls) {
+		BNXT_TF_DBG(ERR, "No action tables for %d:%d\n",
+			    parms.dev_id, parms.act_tid);
+		return -EINVAL;
+	}
+
+	/* Get the class table entry from device id and act context id */
+	parms.class_tid = class_tid;
+	parms.ctbls = ulp_mapper_class_tbl_list_get(parms.dev_id,
+						    parms.class_tid,
+						    &parms.num_ctbls);
+	if (!parms.ctbls || !parms.num_ctbls) {
+		BNXT_TF_DBG(ERR, "No class tables for %d:%d\n",
+			    parms.dev_id, parms.class_tid);
+		return -EINVAL;
+	}
+
+	/* Get the byte order for the further processing from device params */
+	device_params = bnxt_ulp_device_params_get(parms.dev_id);
+	if (!device_params) {
+		BNXT_TF_DBG(ERR, "No class tables for %d:%d\n",
+			    parms.dev_id, parms.class_tid);
+		return -EINVAL;
+	}
+	parms.order = device_params->byte_order;
+	parms.encap_byte_swap = device_params->encap_byte_swap;
+
+	/* initialize the registry file for further processing */
+	if (!ulp_regfile_init(parms.regfile)) {
+		BNXT_TF_DBG(ERR, "regfile initialization failed.\n");
+		return -EINVAL;
+	}
+
+	/* Allocate a Flow ID for attaching all resources for the flow to.
+	 * Once allocated, all errors have to walk the list of resources and
+	 * free each of them.
+	 */
+	rc = ulp_flow_db_fid_alloc(ulp_ctx,
+				   BNXT_ULP_REGULAR_FLOW_TABLE,
+				   &parms.fid);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "Unable to allocate flow table entry\n");
+		return rc;
+	}
+
+	/* Process the action template list from the selected action table*/
+	rc = ulp_mapper_action_tbls_process(&parms);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "action tables failed creation for %d:%d\n",
+			    parms.dev_id, parms.act_tid);
+		goto flow_error;
+	}
+
+	/* All good. Now process the class template */
+	rc = ulp_mapper_class_tbls_process(&parms);
+	if (rc) {
+		BNXT_TF_DBG(ERR, "class tables failed creation for %d:%d\n",
+			    parms.dev_id, parms.class_tid);
+		goto flow_error;
+	}
+
+	*flow_id = parms.fid;
+
+	return rc;
+
+flow_error:
+	/* Free all resources that were allocated during flow creation */
+	trc = ulp_mapper_flow_destroy(ulp_ctx, parms.fid);
+	if (trc)
+		BNXT_TF_DBG(ERR, "Failed to free all resources rc=%d\n", trc);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.h b/drivers/net/bnxt/tf_ulp/ulp_mapper.h
index 8655728..5f3d46e 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.h
@@ -38,6 +38,21 @@ struct bnxt_ulp_mapper_parms {
 	enum bnxt_ulp_flow_db_tables		tbl_idx;
 };
 
+/*
+ * Function to handle the mapping of the Flow to be compatible
+ * with the underlying hardware.
+ */
+int32_t
+ulp_mapper_flow_create(struct bnxt_ulp_context	*ulp_ctx,
+		       uint32_t		app_priority,
+		       struct ulp_rte_hdr_bitmap  *hdr_bitmap,
+		       struct ulp_rte_hdr_field *hdr_field,
+		       struct ulp_rte_act_bitmap *act,
+		       struct ulp_rte_act_prop *act_prop,
+		       uint32_t		class_tid,
+		       uint32_t		act_tid,
+		       uint32_t		*flow_id);
+
 /* Function that frees all resources associated with the flow. */
 int32_t
 ulp_mapper_flow_destroy(struct bnxt_ulp_context	*ulp_ctx, uint32_t fid);
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_db.c b/drivers/net/bnxt/tf_ulp/ulp_template_db.c
index ba06493..5ec7adc 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_db.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_db.c
@@ -1004,6 +1004,28 @@ struct bnxt_ulp_mapper_ident_info ulp_ident_list[] = {
 	}
 };
 
+struct bnxt_ulp_mapper_tbl_list_info ulp_act_tmpl_list[] = {
+	[((0 << BNXT_ULP_LOG2_MAX_NUM_DEV) | BNXT_ULP_DEVICE_ID_WH_PLUS)] = {
+	.device_name = BNXT_ULP_DEVICE_ID_WH_PLUS,
+	.num_tbls = 1,
+	.start_tbl_idx = 0
+	}
+};
+
+struct bnxt_ulp_mapper_act_tbl_info ulp_act_tbl_list[] = {
+	{
+	.resource_func = BNXT_ULP_RESOURCE_FUNC_INDEX_TABLE,
+	.table_type = TF_TBL_TYPE_EXT,
+	.direction = TF_DIR_RX,
+	.srch_b4_alloc = BNXT_ULP_SEARCH_BEFORE_ALLOC_NO,
+	.result_start_idx = 0,
+	.result_bit_size = 128,
+	.result_num_fields = 26,
+	.encap_num_fields = 0,
+	.regfile_wr_idx = BNXT_ULP_REGFILE_INDEX_ACTION_PTR_MAIN
+	}
+};
+
 struct bnxt_ulp_mapper_result_field_info ulp_act_result_field_list[] = {
 	{
 	.field_bit_size = 14,
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_db.h b/drivers/net/bnxt/tf_ulp/ulp_template_db.h
index 733836a..957b21a 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_db.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_db.h
@@ -12,6 +12,7 @@
 #define ULP_TEMPLATE_DB_H_
 
 #define BNXT_ULP_MAX_NUM_DEVICES 4
+#define BNXT_ULP_LOG2_MAX_NUM_DEV 2
 
 enum bnxt_ulp_action_bit {
 	BNXT_ULP_ACTION_BIT_MARK             = 0x0000000000000001,
@@ -127,6 +128,12 @@ enum bnxt_ulp_result_opc {
 	BNXT_ULP_RESULT_OPC_LAST = 4
 };
 
+enum bnxt_ulp_search_before_alloc {
+	BNXT_ULP_SEARCH_BEFORE_ALLOC_NO = 0,
+	BNXT_ULP_SEARCH_BEFORE_ALLOC_YES = 1,
+	BNXT_ULP_SEARCH_BEFORE_ALLOC_LAST = 2
+};
+
 enum bnxt_ulp_spec_opc {
 	BNXT_ULP_SPEC_OPC_SET_TO_CONSTANT = 0,
 	BNXT_ULP_SPEC_OPC_SET_TO_HDR_FIELD = 1,
diff --git a/drivers/net/bnxt/tf_ulp/ulp_template_struct.h b/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
index e28d049..b7094c5 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
+++ b/drivers/net/bnxt/tf_ulp/ulp_template_struct.h
@@ -17,6 +17,10 @@
 #include "rte_flow.h"
 #include "tf_core.h"
 
+struct ulp_rte_hdr_bitmap {
+	uint64_t	bits;
+};
+
 /* Structure to store the protocol fields */
 #define RTE_PARSER_FLOW_HDR_FIELD_SIZE		16
 struct ulp_rte_hdr_field {
@@ -51,6 +55,13 @@ struct bnxt_ulp_device_params {
 	uint32_t			num_resources_per_flow;
 };
 
+/* Flow Mapper */
+struct bnxt_ulp_mapper_tbl_list_info {
+	uint32_t	device_name;
+	uint32_t	start_tbl_idx;
+	uint32_t	num_tbls;
+};
+
 struct bnxt_ulp_mapper_class_tbl_info {
 	enum bnxt_ulp_resource_func	resource_func;
 	uint32_t	table_type;
@@ -132,7 +143,25 @@ struct bnxt_ulp_mapper_ident_info {
 extern struct bnxt_ulp_device_params ulp_device_params[];
 
 /*
- * The ulp_data_field_list provides the instructions for creating an action
+ * The ulp_class_tmpl_list and ulp_act_tmpl_list are indexed by the dev_id
+ * and template id (either class or action) returned by the matcher.
+ * The result provides the start index and number of entries in the connected
+ * ulp_class_tbl_list/ulp_act_tbl_list.
+ */
+extern struct bnxt_ulp_mapper_tbl_list_info	ulp_class_tmpl_list[];
+extern struct bnxt_ulp_mapper_tbl_list_info	ulp_act_tmpl_list[];
+
+/*
+ * The ulp_class_tbl_list and ulp_act_tbl_list are indexed based on the results
+ * of the template lists.  Each entry describes the high level details of the
+ * table entry to include the start index and number of instructions in the
+ * field lists.
+ */
+extern struct bnxt_ulp_mapper_class_tbl_info	ulp_class_tbl_list[];
+extern struct bnxt_ulp_mapper_act_tbl_info	ulp_act_tbl_list[];
+
+/*
+ * The ulp_class_result_field_list provides the instructions for creating result
  * records such as tcam/em results.
  */
 extern struct bnxt_ulp_mapper_result_field_info	ulp_class_result_field_list[];
