diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index b32dc8bfd4..56946b2520 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -610,6 +610,9 @@ static void cmd_help_long_parsed(void *parsed_result,
 			"set port (port_id) fec_mode auto|off|rs|baser\n"
 			"    set fec mode for a specific port\n\n"
 
+			"enable port <port_id> nic_to_pmd_rx_metadata"
+			"    Allow nic to pmd Rx metadata negotiation\n\n"
+
 			, list_pkt_forwarding_modes()
 		);
 	}
@@ -12621,6 +12624,60 @@ static cmdline_parse_inst_t cmd_show_port_flow_transfer_proxy = {
 	}
 };
 
+/* Allow negotiating Rx metadata between NIC and PMD */
+struct cmd_config_port_rx_metadata {
+	cmdline_fixed_string_t enable;
+	cmdline_fixed_string_t port;
+	uint16_t port_id;
+	cmdline_fixed_string_t nic_to_pmd_rx_metadata;
+};
+
+static void
+cmd_config_port_rx_metadata_parsed(void *parsed_result,
+				__rte_unused struct cmdline *cl,
+				__rte_unused void *data)
+{
+	struct cmd_config_port_rx_metadata *res = parsed_result;
+
+	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
+		return;
+	if (!port_is_stopped(res->port_id)) {
+		fprintf(stderr, "Please stop port %u first\n", res->port_id);
+		return;
+	}
+
+	ports[res->port_id].dev_conf.nic_to_pmd_rx_metadata = 1;
+
+	reset_port(res->port_id);
+}
+
+
+static cmdline_parse_token_string_t cmd_config_port_rx_metadata_enable =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_port_rx_metadata, enable,
+								"enable");
+static cmdline_parse_token_string_t cmd_config_port_rx_metadata_port =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_port_rx_metadata, port,
+								"port");
+static cmdline_parse_token_num_t cmd_config_port_rx_metadata_id =
+	TOKEN_NUM_INITIALIZER(struct cmd_config_port_rx_metadata, port_id,
+								RTE_UINT16);
+static cmdline_parse_token_string_t cmd_config_port_rx_metadata_nic_to_pmd_rx_metadata =
+	TOKEN_STRING_INITIALIZER(struct cmd_config_port_rx_metadata, nic_to_pmd_rx_metadata,
+								"nic_to_pmd_rx_metadata");
+
+static cmdline_parse_inst_t cmd_config_port_rx_metadata_parse = {
+	.f = cmd_config_port_rx_metadata_parsed,
+	.data = NULL,
+	.help_str = "enable port <port_id> nic_to_pmd_rx_metadata",
+	.tokens = {
+		(void *)&cmd_config_port_rx_metadata_enable,
+		(void *)&cmd_config_port_rx_metadata_port,
+		(void *)&cmd_config_port_rx_metadata_id,
+		(void *)&cmd_config_port_rx_metadata_nic_to_pmd_rx_metadata,
+		NULL,
+	},
+};
+
 /* ******************************************************************************** */
 
 /* list of instructions */
@@ -12851,6 +12908,7 @@ static cmdline_parse_ctx_t builtin_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_show_capability,
 	(cmdline_parse_inst_t *)&cmd_set_flex_is_pattern,
 	(cmdline_parse_inst_t *)&cmd_set_flex_spec_pattern,
+	(cmdline_parse_inst_t *)&cmd_config_port_rx_metadata_parse,
 	NULL,
 };
 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index acccb6b035..47fce3accb 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -3249,6 +3249,15 @@ port_flow_create(portid_t port_id,
 		}
 		id = port->flow_list->id + 1;
 	}
+
+	if (port->dev_conf.nic_to_pmd_rx_metadata == 0 &&
+	   (actions->type == RTE_FLOW_ACTION_TYPE_MARK ||
+	    actions->type == RTE_FLOW_ACTION_TYPE_FLAG)) {
+		fprintf(stderr,
+			"rx metadata is not negotiated with PMD\n");
+		return -EINVAL;
+	}
+
 	if (tunnel_ops->enabled) {
 		pft = port_flow_tunnel_offload_cmd_prep(port_id, pattern,
 							actions, tunnel_ops);
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 134d79a555..22e5e08fc1 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -1604,8 +1604,6 @@ init_config_port_offloads(portid_t pid, uint32_t socket_id)
 	int ret;
 	int i;
 
-	eth_rx_metadata_negotiate_mp(pid);
-
 	port->dev_conf.txmode = tx_mode;
 	port->dev_conf.rxmode = rx_mode;
 
@@ -2946,6 +2944,9 @@ start_port(portid_t pid)
 				port->update_conf = 0;
 			}
 
+			if (port->dev_conf.nic_to_pmd_rx_metadata)
+				eth_rx_metadata_negotiate_mp(pi);
+
 			/* configure port */
 			diag = eth_dev_configure_mp(pi, nb_rxq + nb_hairpinq,
 						     nb_txq + nb_hairpinq,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 0037506a79..024dbf6012 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -1558,6 +1558,12 @@ Enable or disable a per port Rx offloading on all Rx queues of a port::
 
 This command should be run when the port is stopped, or else it will fail.
 
+Enable Rx metadata negotiation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enable NIC to PMD Rx metadata negotiation::
+   testpmd> enable port <port_id> nic_to_pmd_rx_metadata
+
 config per queue Rx offloading
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
