diff --git a/doc/guides/nics/cpfl.rst b/doc/guides/nics/cpfl.rst
index 39a2b603f3..83a18c3f2e 100644
--- a/doc/guides/nics/cpfl.rst
+++ b/doc/guides/nics/cpfl.rst
@@ -92,6 +92,42 @@ Runtime Configuration
   Then the PMD will configure Tx queue with single queue mode.
   Otherwise, split queue mode is chosen by default.
 
+- ``representor`` (default ``not enabled``)
+
+  The cpfl PMD supports the creation of APF/CPF/VF port representors.
+  Each port representor corresponds to a single function of that device.
+  Using the ``devargs`` option ``representor`` the user can specify
+  which functions to create port representors.
+
+  Format is::
+
+    [[c<controller_id>]pf<pf_id>]vf<vf_id>
+
+  Controller_id 0 is host (default), while 1 is accelerator core.
+  Pf_id 0 is APF (default), while 1 is CPF.
+  Default value can be omitted.
+
+  Create 4 representors for 4 vfs on host APF::
+
+    -a BDF,representor=c0pf0vf[0-3]
+
+  Or::
+
+    -a BDF,representor=pf0vf[0-3]
+
+  Or::
+
+    -a BDF,representor=vf[0-3]
+
+  Create a representor for CPF on accelerator core::
+
+    -a BDF,representor=c1pf1
+
+  Multiple representor devargs are supported. Create 4 representors for 4
+  vfs on host APF and one representor for CPF on accelerator core::
+
+    -a BDF,representor=vf[0-3],representor=c1pf1
+
 
 Driver compilation and testing
 ------------------------------
diff --git a/doc/guides/rel_notes/release_23_11.rst b/doc/guides/rel_notes/release_23_11.rst
index 333e1d95a2..3d9be208d0 100644
--- a/doc/guides/rel_notes/release_23_11.rst
+++ b/doc/guides/rel_notes/release_23_11.rst
@@ -78,6 +78,9 @@ New Features
 * build: Optional libraries can now be selected with the new ``enable_libs``
   build option similarly to the existing ``enable_drivers`` build option.
 
+* **Updated Intel cpfl driver.**
+
+  * Added support for port representor.
 
 Removed Items
 -------------
diff --git a/drivers/net/cpfl/cpfl_ethdev.c b/drivers/net/cpfl/cpfl_ethdev.c
index ad21f901bb..eb57e355d2 100644
--- a/drivers/net/cpfl/cpfl_ethdev.c
+++ b/drivers/net/cpfl/cpfl_ethdev.c
@@ -13,8 +13,10 @@
 #include <rte_hash_crc.h>
 
 #include "cpfl_ethdev.h"
+#include <ethdev_private.h>
 #include "cpfl_rxtx.h"
 
+#define CPFL_REPRESENTOR	"representor"
 #define CPFL_TX_SINGLE_Q	"tx_single"
 #define CPFL_RX_SINGLE_Q	"rx_single"
 #define CPFL_VPORT		"vport"
@@ -25,6 +27,7 @@ struct cpfl_adapter_list cpfl_adapter_list;
 bool cpfl_adapter_list_init;
 
 static const char * const cpfl_valid_args[] = {
+	CPFL_REPRESENTOR,
 	CPFL_TX_SINGLE_Q,
 	CPFL_RX_SINGLE_Q,
 	CPFL_VPORT,
@@ -1407,6 +1410,128 @@ parse_bool(const char *key, const char *value, void *args)
 	return 0;
 }
 
+static int
+enlist(uint16_t *list, uint16_t *len_list, const uint16_t max_list, uint16_t val)
+{
+	uint16_t i;
+
+	for (i = 0; i < *len_list; i++) {
+		if (list[i] == val)
+			return 0;
+	}
+	if (*len_list >= max_list)
+		return -1;
+	list[(*len_list)++] = val;
+	return 0;
+}
+
+static const char *
+process_range(const char *str, uint16_t *list, uint16_t *len_list,
+	const uint16_t max_list)
+{
+	uint16_t lo, hi, val;
+	int result, n = 0;
+	const char *pos = str;
+
+	result = sscanf(str, "%hu%n-%hu%n", &lo, &n, &hi, &n);
+	if (result == 1) {
+		if (enlist(list, len_list, max_list, lo) != 0)
+			return NULL;
+	} else if (result == 2) {
+		if (lo > hi)
+			return NULL;
+		for (val = lo; val <= hi; val++) {
+			if (enlist(list, len_list, max_list, val) != 0)
+				return NULL;
+		}
+	} else {
+		return NULL;
+	}
+	return pos + n;
+}
+
+static const char *
+process_list(const char *str, uint16_t *list, uint16_t *len_list, const uint16_t max_list)
+{
+	const char *pos = str;
+
+	if (*pos == '[')
+		pos++;
+	while (1) {
+		pos = process_range(pos, list, len_list, max_list);
+		if (pos == NULL)
+			return NULL;
+		if (*pos != ',') /* end of list */
+			break;
+		pos++;
+	}
+	if (*str == '[' && *pos != ']')
+		return NULL;
+	if (*pos == ']')
+		pos++;
+	return pos;
+}
+
+static int
+parse_repr(const char *key __rte_unused, const char *value, void *args)
+{
+	struct cpfl_devargs *devargs = args;
+	struct rte_eth_devargs *eth_da;
+	const char *str = value;
+
+	if (devargs->repr_args_num == CPFL_REPR_ARG_NUM_MAX)
+		return -EINVAL;
+
+	eth_da = &devargs->repr_args[devargs->repr_args_num];
+
+	if (str[0] == 'c') {
+		str += 1;
+		str = process_list(str, eth_da->mh_controllers,
+				&eth_da->nb_mh_controllers,
+				RTE_DIM(eth_da->mh_controllers));
+		if (str == NULL)
+			goto done;
+	}
+	if (str[0] == 'p' && str[1] == 'f') {
+		eth_da->type = RTE_ETH_REPRESENTOR_PF;
+		str += 2;
+		str = process_list(str, eth_da->ports,
+				&eth_da->nb_ports, RTE_DIM(eth_da->ports));
+		if (str == NULL || str[0] == '\0')
+			goto done;
+	} else if (eth_da->nb_mh_controllers > 0) {
+		/* 'c' must followed by 'pf'. */
+		str = NULL;
+		goto done;
+	}
+	if (str[0] == 'v' && str[1] == 'f') {
+		eth_da->type = RTE_ETH_REPRESENTOR_VF;
+		str += 2;
+	} else if (str[0] == 's' && str[1] == 'f') {
+		eth_da->type = RTE_ETH_REPRESENTOR_SF;
+		str += 2;
+	} else {
+		/* 'pf' must followed by 'vf' or 'sf'. */
+		if (eth_da->type == RTE_ETH_REPRESENTOR_PF) {
+			str = NULL;
+			goto done;
+		}
+		eth_da->type = RTE_ETH_REPRESENTOR_VF;
+	}
+	str = process_list(str, eth_da->representor_ports,
+		&eth_da->nb_representor_ports,
+		RTE_DIM(eth_da->representor_ports));
+done:
+	if (str == NULL) {
+		RTE_LOG(ERR, EAL, "wrong representor format: %s\n", str);
+		return -1;
+	}
+
+	devargs->repr_args_num++;
+
+	return 0;
+}
+
 static int
 cpfl_parse_devargs(struct rte_pci_device *pci_dev, struct cpfl_adapter_ext *adapter)
 {
@@ -1431,6 +1556,12 @@ cpfl_parse_devargs(struct rte_pci_device *pci_dev, struct cpfl_adapter_ext *adap
 		return -EINVAL;
 	}
 
+	cpfl_args->repr_args_num = 0;
+	ret = rte_kvargs_process(kvlist, CPFL_REPRESENTOR, &parse_repr, cpfl_args);
+
+	if (ret != 0)
+		goto fail;
+
 	ret = rte_kvargs_process(kvlist, CPFL_VPORT, &parse_vport,
 				 cpfl_args);
 	if (ret != 0)
@@ -2087,6 +2218,48 @@ cpfl_vport_devargs_process(struct cpfl_adapter_ext *adapter)
 	return 0;
 }
 
+static int
+cpfl_repr_devargs_process(struct cpfl_adapter_ext *adapter)
+{
+	struct cpfl_devargs *devargs = &adapter->devargs;
+	int i, j;
+
+	/* check and refine repr args */
+	for (i = 0; i < devargs->repr_args_num; i++) {
+		struct rte_eth_devargs *eth_da = &devargs->repr_args[i];
+
+		/* set default host_id to xeon host */
+		if (eth_da->nb_mh_controllers == 0) {
+			eth_da->nb_mh_controllers = 1;
+			eth_da->mh_controllers[0] = CPFL_HOST_ID_HOST;
+		} else {
+			for (j = 0; j < eth_da->nb_mh_controllers; j++) {
+				if (eth_da->mh_controllers[j] > CPFL_HOST_ID_ACC) {
+					PMD_INIT_LOG(ERR, "Invalid Host ID %d",
+						     eth_da->mh_controllers[j]);
+					return -EINVAL;
+				}
+			}
+		}
+
+		/* set default pf to APF */
+		if (eth_da->nb_ports == 0) {
+			eth_da->nb_ports = 1;
+			eth_da->ports[0] = CPFL_PF_TYPE_APF;
+		} else {
+			for (j = 0; j < eth_da->nb_ports; j++) {
+				if (eth_da->ports[j] > CPFL_PF_TYPE_CPF) {
+					PMD_INIT_LOG(ERR, "Invalid Host ID %d",
+						     eth_da->ports[j]);
+					return -EINVAL;
+				}
+			}
+		}
+	}
+
+	return 0;
+}
+
 static int
 cpfl_vport_create(struct rte_pci_device *pci_dev, struct cpfl_adapter_ext *adapter)
 {
@@ -2165,6 +2338,12 @@ cpfl_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 		goto err;
 	}
 
+	retval = cpfl_repr_devargs_process(adapter);
+	if (retval != 0) {
+		PMD_INIT_LOG(ERR, "Failed to process repr devargs");
+		goto err;
+	}
+
 	return 0;
 
 err:
diff --git a/drivers/net/cpfl/cpfl_ethdev.h b/drivers/net/cpfl/cpfl_ethdev.h
index 4975c05a55..b03666f5ea 100644
--- a/drivers/net/cpfl/cpfl_ethdev.h
+++ b/drivers/net/cpfl/cpfl_ethdev.h
@@ -60,16 +60,24 @@
 #define IDPF_DEV_ID_CPF			0x1453
 #define VIRTCHNL2_QUEUE_GROUP_P2P	0x100
 
+#define CPFL_HOST_ID_HOST	0
+#define CPFL_HOST_ID_ACC	1
+#define CPFL_PF_TYPE_APF	0
+#define CPFL_PF_TYPE_CPF	1
+
 struct cpfl_vport_param {
 	struct cpfl_adapter_ext *adapter;
 	uint16_t devarg_id; /* arg id from user */
 	uint16_t idx;       /* index in adapter->vports[]*/
 };
 
+#define CPFL_REPR_ARG_NUM_MAX	4
 /* Struct used when parse driver specific devargs */
 struct cpfl_devargs {
 	uint16_t req_vports[CPFL_MAX_VPORT_NUM];
 	uint16_t req_vport_nb;
+	uint8_t repr_args_num;
+	struct rte_eth_devargs repr_args[CPFL_REPR_ARG_NUM_MAX];
 };
 
 struct p2p_queue_chunks_info {
