diff --git a/doc/guides/prog_guide/eventdev.rst b/doc/guides/prog_guide/eventdev.rst
index a49e486a30..afee674ee1 100644
--- a/doc/guides/prog_guide/eventdev.rst
+++ b/doc/guides/prog_guide/eventdev.rst
@@ -412,6 +412,41 @@ An event driven worker thread has following typical workflow on fastpath:
                rte_event_enqueue_burst(...);
        }
 
+Quiescing Event Ports
+~~~~~~~~~~~~~~~~~~~~~
+
+To migrate the event port to another lcore or while tearing down a worker core
+using an event port ``rte_event_port_quiesce()`` can be invoked to make sure
+that all the data associated with the event port are released from the worker
+core, this might also include any prefetched events.
+
+A flush callback can be passed to the function to handle any outstanding events.
+
+.. code-block:: c
+
+        rte_event_port_quiesce(dev_id, port_id, release_cb, NULL);
+
+.. Note::
+
+         The event port specific config shall not be reset when this API is
+         invoked.
+
+Stopping the EventDev
+~~~~~~~~~~~~~~~~~~~~~
+
+A single function call tells the eventdev instance to stop processing
+events. A flush callback can be registered to free any inflight events
+using ``rte_event_dev_stop_flush_callback_register()`` function.
+
+.. code-block:: c
+
+        int err = rte_event_dev_stop(dev_id);
+
+.. Note::
+
+         The event producers such as event_eth_rx_adapter, event_timer_adapter
+         and event_crypto_adapter need to be stopped before stopping the event
+         device.
 
 Summary
 -------
diff --git a/lib/eventdev/eventdev_pmd.h b/lib/eventdev/eventdev_pmd.h
index ce469d47a6..6173f22b9b 100644
--- a/lib/eventdev/eventdev_pmd.h
+++ b/lib/eventdev/eventdev_pmd.h
@@ -381,6 +381,23 @@ typedef int (*eventdev_port_setup_t)(struct rte_eventdev *dev,
  */
 typedef void (*eventdev_port_release_t)(void *port);
 
+/**
+ * Quiesce any core specific resources consumed by the event port
+ *
+ * @param dev
+ *   Event device pointer.
+ * @param port
+ *   Event port pointer.
+ * @param flush_cb
+ *   User-provided event flush function.
+ * @param args
+ *   Arguments to be passed to the user-provided event flush function.
+ *
+ */
+typedef void (*eventdev_port_quiesce_t)(struct rte_eventdev *dev, void *port,
+					rte_eventdev_port_flush_t flush_cb,
+					void *args);
+
 /**
  * Link multiple source event queues to destination event port.
  *
@@ -1218,6 +1235,8 @@ struct eventdev_ops {
 	/**< Set up an event port. */
 	eventdev_port_release_t port_release;
 	/**< Release an event port. */
+	eventdev_port_quiesce_t port_quiesce;
+	/**< Quiesce an event port. */
 
 	eventdev_port_link_t port_link;
 	/**< Link event queues to an event port. */
diff --git a/lib/eventdev/rte_eventdev.c b/lib/eventdev/rte_eventdev.c
index 532a253553..0250e57f24 100644
--- a/lib/eventdev/rte_eventdev.c
+++ b/lib/eventdev/rte_eventdev.c
@@ -730,6 +730,25 @@ rte_event_port_setup(uint8_t dev_id, uint8_t port_id,
 	return 0;
 }
 
+void
+rte_event_port_quiesce(uint8_t dev_id, uint8_t port_id,
+		       rte_eventdev_port_flush_t release_cb, void *args)
+{
+	struct rte_eventdev *dev;
+
+	RTE_EVENTDEV_VALID_DEVID_OR_RET(dev_id);
+	dev = &rte_eventdevs[dev_id];
+
+	if (!is_valid_port(dev, port_id)) {
+		RTE_EDEV_LOG_ERR("Invalid port_id=%" PRIu8, port_id);
+		return;
+	}
+
+	if (dev->dev_ops->port_quiesce)
+		(*dev->dev_ops->port_quiesce)(dev, dev->data->ports[port_id],
+					      release_cb, args);
+}
+
 int
 rte_event_dev_attr_get(uint8_t dev_id, uint32_t attr_id,
 		       uint32_t *attr_value)
diff --git a/lib/eventdev/rte_eventdev.h b/lib/eventdev/rte_eventdev.h
index 42a5660169..1a46d289a9 100644
--- a/lib/eventdev/rte_eventdev.h
+++ b/lib/eventdev/rte_eventdev.h
@@ -830,6 +830,43 @@ int
 rte_event_port_setup(uint8_t dev_id, uint8_t port_id,
 		     const struct rte_event_port_conf *port_conf);
 
+typedef void (*rte_eventdev_port_flush_t)(uint8_t dev_id,
+					  struct rte_event event, void *arg);
+/**< Callback function prototype that can be passed during
+ * rte_event_port_release(), invoked once per a released event.
+ */
+
+/**
+ * Quiesce any core specific resources consumed by the event port.
+ *
+ * Event ports are generally coupled with lcores, and a given Hardware
+ * implementation might require the PMD to store port specific data in the
+ * lcore.
+ * When the application decides to migrate the event port to another lcore
+ * or teardown the current lcore it may to call `rte_event_port_quiesce`
+ * to make sure that all the data associated with the event port are released
+ * from the lcore, this might also include any prefetched events.
+ * While releasing the event port from the lcore, this function calls the
+ * user-provided flush callback once per event.
+ *
+ * @note The event port specific config shall not be reset when this API is
+ * called.
+ *
+ * @param dev_id
+ *   The identifier of the device.
+ * @param port_id
+ *   The index of the event port to setup. The value must be in the range
+ *   [0, nb_event_ports - 1] previously supplied to rte_event_dev_configure().
+ * @param release_cb
+ *   Callback function invoked once per flushed event.
+ * @param args
+ *   Argument supplied to callback.
+ */
+__rte_experimental
+void
+rte_event_port_quiesce(uint8_t dev_id, uint8_t port_id,
+		       rte_eventdev_port_flush_t release_cb, void *args);
+
 /**
  * The queue depth of the port on the enqueue side
  */
diff --git a/lib/eventdev/version.map b/lib/eventdev/version.map
index cd5dada07f..1907093539 100644
--- a/lib/eventdev/version.map
+++ b/lib/eventdev/version.map
@@ -108,6 +108,9 @@ EXPERIMENTAL {
 
 	# added in 22.03
 	rte_event_eth_rx_adapter_event_port_get;
+
+	# added in 22.07
+	rte_event_port_quiesce;
 };
 
 INTERNAL {
