diff --git a/app/test-flow-perf/actions_gen.c b/app/test-flow-perf/actions_gen.c
index 7c209f7266..13e1b82389 100644
--- a/app/test-flow-perf/actions_gen.c
+++ b/app/test-flow-perf/actions_gen.c
@@ -29,6 +29,7 @@ struct additional_para {
 	uint32_t counter;
 	uint64_t encap_data;
 	uint64_t decap_data;
+	uint16_t dst_port;
 	uint8_t core_idx;
 	bool unique_data;
 };
@@ -171,12 +172,13 @@ add_set_tag(struct rte_flow_action *actions,
 static void
 add_port_id(struct rte_flow_action *actions,
 	uint8_t actions_counter,
-	__rte_unused struct additional_para para)
+	struct additional_para para)
 {
 	static struct rte_flow_action_port_id port_id = {
 		.id = PORT_ID_DST,
 	};
 
+	port_id.id = para.dst_port;
 	actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_PORT_ID;
 	actions[actions_counter].conf = &port_id;
 }
@@ -909,7 +911,7 @@ void
 fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
 	uint32_t counter, uint16_t next_table, uint16_t hairpinq,
 	uint64_t encap_data, uint64_t decap_data, uint8_t core_idx,
-	bool unique_data, uint8_t rx_queues_count)
+	bool unique_data, uint8_t rx_queues_count, uint16_t dst_port)
 {
 	struct additional_para additional_para_data;
 	uint8_t actions_counter = 0;
@@ -933,6 +935,7 @@ fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
 		.decap_data = decap_data,
 		.core_idx = core_idx,
 		.unique_data = unique_data,
+		.dst_port = dst_port,
 	};
 
 	if (hairpinq != 0) {
diff --git a/app/test-flow-perf/actions_gen.h b/app/test-flow-perf/actions_gen.h
index 8990686269..9e13b164f9 100644
--- a/app/test-flow-perf/actions_gen.h
+++ b/app/test-flow-perf/actions_gen.h
@@ -20,6 +20,6 @@
 void fill_actions(struct rte_flow_action *actions, uint64_t *flow_actions,
 	uint32_t counter, uint16_t next_table, uint16_t hairpinq,
 	uint64_t encap_data, uint64_t decap_data, uint8_t core_idx,
-	bool unique_data, uint8_t rx_queues_count);
+	bool unique_data, uint8_t rx_queues_count, uint16_t dst_port);
 
 #endif /* FLOW_PERF_ACTION_GEN */
diff --git a/app/test-flow-perf/flow_gen.c b/app/test-flow-perf/flow_gen.c
index 51871dbfdc..c7b7652c02 100644
--- a/app/test-flow-perf/flow_gen.c
+++ b/app/test-flow-perf/flow_gen.c
@@ -45,6 +45,7 @@ generate_flow(uint16_t port_id,
 	uint16_t hairpinq,
 	uint64_t encap_data,
 	uint64_t decap_data,
+	uint16_t dst_port,
 	uint8_t core_idx,
 	uint8_t rx_queues_count,
 	bool unique_data,
@@ -64,7 +65,7 @@ generate_flow(uint16_t port_id,
 	fill_actions(actions, flow_actions,
 		outer_ip_src, next_table, hairpinq,
 		encap_data, decap_data, core_idx,
-		unique_data, rx_queues_count);
+		unique_data, rx_queues_count, dst_port);
 
 	fill_items(items, flow_items, outer_ip_src, core_idx);
 
diff --git a/app/test-flow-perf/flow_gen.h b/app/test-flow-perf/flow_gen.h
index 1118a9fc14..46ce575ff8 100644
--- a/app/test-flow-perf/flow_gen.h
+++ b/app/test-flow-perf/flow_gen.h
@@ -34,6 +34,7 @@ generate_flow(uint16_t port_id,
 	uint16_t hairpinq,
 	uint64_t encap_data,
 	uint64_t decap_data,
+	uint16_t dst_port,
 	uint8_t core_idx,
 	uint8_t rx_queues_count,
 	bool unique_data,
diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 3ebc025fb2..c1ad9bb0a3 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -56,6 +56,7 @@ static uint64_t flow_attrs[MAX_ATTRS_NUM];
 static uint8_t items_idx, actions_idx, attrs_idx;
 
 static uint64_t ports_mask;
+static uint16_t dst_ports[RTE_MAX_ETHPORTS];
 static volatile bool force_quit;
 static bool dump_iterations;
 static bool delete_flag;
@@ -619,7 +620,7 @@ args_parse(int argc, char **argv)
 		{ "icmpv4",                     0, 0, 0 },
 		{ "icmpv6",                     0, 0, 0 },
 		/* Actions */
-		{ "port-id",                    0, 0, 0 },
+		{ "port-id",                    2, 0, 0 },
 		{ "rss",                        0, 0, 0 },
 		{ "queue",                      0, 0, 0 },
 		{ "jump",                       0, 0, 0 },
@@ -657,6 +658,9 @@ args_parse(int argc, char **argv)
 	RTE_ETH_FOREACH_DEV(i)
 		ports_mask |= 1 << i;
 
+	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
+		dst_ports[i] = PORT_ID_DST;
+
 	hairpin_queues_num = 0;
 	argvopt = argv;
 
@@ -811,6 +815,17 @@ args_parse(int argc, char **argv)
 					rte_exit(EXIT_FAILURE, "Invalid fwd port mask\n");
 				ports_mask = pm;
 			}
+			if (strcmp(lgopts[opt_idx].name,
+					"port-id") == 0) {
+				uint16_t port_idx = 0;
+				char *token;
+
+				token = strtok(optarg, ",");
+				while (token != NULL) {
+					dst_ports[port_idx++] = atoi(token);
+					token = strtok(NULL, ",");
+				}
+			}
 			if (strcmp(lgopts[opt_idx].name, "rxq") == 0) {
 				n = atoi(optarg);
 				rx_queues_count = (uint8_t) n;
@@ -1180,7 +1195,7 @@ destroy_flows(int port_id, uint8_t core_id, struct rte_flow **flows_list)
 }
 
 static struct rte_flow **
-insert_flows(int port_id, uint8_t core_id)
+insert_flows(int port_id, uint8_t core_id, uint16_t dst_port_id)
 {
 	struct rte_flow **flows_list;
 	struct rte_flow_error error;
@@ -1226,8 +1241,8 @@ insert_flows(int port_id, uint8_t core_id)
 		 */
 		flow = generate_flow(port_id, 0, flow_attrs,
 			global_items, global_actions,
-			flow_group, 0, 0, 0, 0, core_id, rx_queues_count,
-			unique_data, &error);
+			flow_group, 0, 0, 0, 0, dst_port_id, core_id,
+			rx_queues_count, unique_data, &error);
 
 		if (flow == NULL) {
 			print_flow_error(error);
@@ -1241,8 +1256,8 @@ insert_flows(int port_id, uint8_t core_id)
 		flow = generate_flow(port_id, flow_group,
 			flow_attrs, flow_items, flow_actions,
 			JUMP_ACTION_TABLE, counter,
-			hairpin_queues_num,
-			encap_data, decap_data,
+			hairpin_queues_num, encap_data,
+			decap_data, dst_port_id,
 			core_id, rx_queues_count,
 			unique_data, &error);
 
@@ -1304,6 +1319,7 @@ static void
 flows_handler(uint8_t core_id)
 {
 	struct rte_flow **flows_list;
+	uint16_t port_idx = 0;
 	uint16_t nr_ports;
 	int port_id;
 
@@ -1323,7 +1339,8 @@ flows_handler(uint8_t core_id)
 		mc_pool.last_alloc[core_id] = (int64_t)dump_socket_mem(stdout);
 		if (has_meter())
 			meters_handler(port_id, core_id, METER_CREATE);
-		flows_list = insert_flows(port_id, core_id);
+		flows_list = insert_flows(port_id, core_id,
+						dst_ports[port_idx++]);
 		if (flows_list == NULL)
 			rte_exit(EXIT_FAILURE, "Error: Insertion Failed!\n");
 		mc_pool.current_alloc[core_id] = (int64_t)dump_socket_mem(stdout);
diff --git a/doc/guides/tools/flow-perf.rst b/doc/guides/tools/flow-perf.rst
index 0855f88689..9812b43a74 100644
--- a/doc/guides/tools/flow-perf.rst
+++ b/doc/guides/tools/flow-perf.rst
@@ -230,6 +230,9 @@ Actions:
 	Add port redirection action to all flows actions.
 	Port redirection destination is defined in user_parameters.h
 	under PORT_ID_DST, default value = 1.
+       It can also has optional parameter like --port-id=N[,M] to
+       specify the destination port, the number of values should be
+       the same with number of set bits in portmask.
 
 *	``--rss``
 	Add RSS action to all flows actions,
