diff --git a/doc/guides/prog_guide/img/rte_flow_async_init.svg b/doc/guides/prog_guide/img/rte_flow_async_init.svg
new file mode 100644
index 0000000000..f66e9c73d7
--- /dev/null
+++ b/doc/guides/prog_guide/img/rte_flow_async_init.svg
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- SPDX-License-Identifier: BSD-3-Clause -->
+
+<!-- Copyright(c) 2022 NVIDIA Corporation & Affiliates -->
+
+<svg
+   width="485"
+   height="535"
+   overflow="hidden"
+   version="1.1"
+   id="svg61"
+   sodipodi:docname="rte_flow_async_init.svg"
+   inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview63"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     showgrid="false"
+     inkscape:zoom="1.517757"
+     inkscape:cx="242.79249"
+     inkscape:cy="267.17057"
+     inkscape:window-width="2400"
+     inkscape:window-height="1271"
+     inkscape:window-x="2391"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g59" />
+  <defs
+     id="defs5">
+    <clipPath
+       id="clip0">
+      <rect
+         x="0"
+         y="0"
+         width="485"
+         height="535"
+         id="rect2" />
+    </clipPath>
+  </defs>
+  <g
+     clip-path="url(#clip0)"
+     id="g59">
+    <rect
+       x="0"
+       y="0"
+       width="485"
+       height="535"
+       fill="#FFFFFF"
+       id="rect7" />
+    <rect
+       x="0.500053"
+       y="79.5001"
+       width="482"
+       height="59"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#A6A6A6"
+       id="rect9" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="24"
+       transform="translate(121.6 116)"
+       id="text13">
+         rte_eth_dev_configure
+         <tspan
+   font-size="24"
+   x="224.007"
+   y="0"
+   id="tspan11">()</tspan></text>
+    <rect
+       x="0.500053"
+       y="158.5"
+       width="482"
+       height="59"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#FFFFFF"
+       id="rect15" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="24"
+       transform="translate(140.273 195)"
+       id="text17">
+         rte_flow_configure()
+      </text>
+    <rect
+       x="0.500053"
+       y="236.5"
+       width="482"
+       height="60"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#FFFFFF"
+       id="rect19" />
+    <text
+       font-family="Calibri, Calibri_MSFontService, sans-serif"
+       font-weight="400"
+       font-size="24px"
+       id="text21"
+       x="63.425903"
+       y="274">rte_flow_pattern_template_create()</text>
+    <rect
+       x="0.500053"
+       y="316.5"
+       width="482"
+       height="59"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#FFFFFF"
+       id="rect23" />
+    <text
+       font-family="Calibri, Calibri_MSFontService, sans-serif"
+       font-weight="400"
+       font-size="24px"
+       id="text27"
+       x="69.379204"
+       y="353">rte_flow_actions_template_create()</text>
+    <rect
+       x="0.500053"
+       y="0.500053"
+       width="482"
+       height="60"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#A6A6A6"
+       id="rect29" />
+    <text
+       font-family="Calibri, Calibri_MSFontService, sans-serif"
+       font-weight="400"
+       font-size="24px"
+       transform="translate(177.233,37)"
+       id="text33">rte_eal_init()</text>
+    <path
+       d="M2-1.09108e-05 2.00005 9.2445-1.99995 9.24452-2 1.09108e-05ZM6.00004 7.24448 0.000104987 19.2445-5.99996 7.24455Z"
+       transform="matrix(-1 0 0 1 241 60)"
+       id="path35" />
+    <path
+       d="M2-1.08133e-05 2.00005 9.41805-1.99995 9.41807-2 1.08133e-05ZM6.00004 7.41802 0.000104987 19.4181-5.99996 7.41809Z"
+       transform="matrix(-1 0 0 1 241 138)"
+       id="path37" />
+    <path
+       d="M2-1.09108e-05 2.00005 9.2445-1.99995 9.24452-2 1.09108e-05ZM6.00004 7.24448 0.000104987 19.2445-5.99996 7.24455Z"
+       transform="matrix(-1 0 0 1 241 217)"
+       id="path39" />
+    <rect
+       x="0.500053"
+       y="395.5"
+       width="482"
+       height="59"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#FFFFFF"
+       id="rect41" />
+    <text
+       font-family="Calibri, Calibri_MSFontService, sans-serif"
+       font-weight="400"
+       font-size="24px"
+       id="text47"
+       x="76.988998"
+       y="432">rte_flow_template_table_create()</text>
+    <path
+       d="M2-1.05859e-05 2.00005 9.83526-1.99995 9.83529-2 1.05859e-05ZM6.00004 7.83524 0.000104987 19.8353-5.99996 7.83531Z"
+       transform="matrix(-1 0 0 1 241 296)"
+       id="path49" />
+    <path
+       d="M243 375 243 384.191 239 384.191 239 375ZM247 382.191 241 394.191 235 382.191Z"
+       id="path51" />
+    <rect
+       x="0.500053"
+       y="473.5"
+       width="482"
+       height="60"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#A6A6A6"
+       id="rect53" />
+    <text
+       font-family="Calibri, Calibri_MSFontService, sans-serif"
+       font-weight="400"
+       font-size="24px"
+       id="text55"
+       x="149.30299"
+       y="511">rte_eth_dev_start()</text>
+    <path
+       d="M245 454 245 463.191 241 463.191 241 454ZM249 461.191 243 473.191 237 461.191Z"
+       id="path57" />
+  </g>
+</svg>
diff --git a/doc/guides/prog_guide/img/rte_flow_async_usage.svg b/doc/guides/prog_guide/img/rte_flow_async_usage.svg
new file mode 100644
index 0000000000..bb978bca1e
--- /dev/null
+++ b/doc/guides/prog_guide/img/rte_flow_async_usage.svg
@@ -0,0 +1,354 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- SPDX-License-Identifier: BSD-3-Clause -->
+
+<!-- Copyright(c) 2022 NVIDIA Corporation & Affiliates -->
+
+<svg
+   width="880"
+   height="610"
+   overflow="hidden"
+   version="1.1"
+   id="svg103"
+   sodipodi:docname="rte_flow_async_usage.svg"
+   inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview105"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     showgrid="false"
+     inkscape:zoom="1.3311475"
+     inkscape:cx="439.84607"
+     inkscape:cy="305.37563"
+     inkscape:window-width="2400"
+     inkscape:window-height="1271"
+     inkscape:window-x="-9"
+     inkscape:window-y="-9"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="g101" />
+  <defs
+     id="defs5">
+    <clipPath
+       id="clip0">
+      <rect
+         x="0"
+         y="0"
+         width="880"
+         height="610"
+         id="rect2" />
+    </clipPath>
+  </defs>
+  <g
+     clip-path="url(#clip0)"
+     id="g101">
+    <rect
+       x="0"
+       y="0"
+       width="880"
+       height="610"
+       fill="#FFFFFF"
+       id="rect7" />
+    <rect
+       x="333.5"
+       y="0.500053"
+       width="234"
+       height="45"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#A6A6A6"
+       id="rect9" />
+    <text
+       font-family="Consolas, Consolas_MSFontService, sans-serif"
+       font-weight="400"
+       font-size="19px"
+       transform="translate(357.196,29)"
+       id="text11">rte_eth_rx_burst()</text>
+    <rect
+       x="333.5"
+       y="63.5001"
+       width="234"
+       height="45"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#D9D9D9"
+       id="rect13" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="19"
+       transform="translate(394.666 91)"
+       id="text17">analyze <tspan
+   font-size="19"
+   x="60.9267"
+   y="0"
+   id="tspan15">packet </tspan></text>
+    <rect
+       x="587.84119"
+       y="279.47534"
+       width="200.65393"
+       height="46.049305"
+       stroke="#000000"
+       stroke-width="1.20888"
+       stroke-miterlimit="8"
+       fill="#ffffff"
+       id="rect19" />
+    <text
+       font-family="Calibri, Calibri_MSFontService, sans-serif"
+       font-weight="400"
+       font-size="19px"
+       id="text21"
+       x="595.42902"
+       y="308">rte_flow_async_create()</text>
+    <path
+       d="M333.5 384 450.5 350.5 567.5 384 450.5 417.5Z"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#D9D9D9"
+       fill-rule="evenodd"
+       id="path23" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="19"
+       transform="translate(430.069 378)"
+       id="text27">more <tspan
+   font-size="19"
+   x="-12.94"
+   y="23"
+   id="tspan25">packets?</tspan></text>
+    <path
+       d="M689.249 325.5 689.249 338.402 450.5 338.402 450.833 338.069 450.833 343.971 450.167 343.971 450.167 337.735 688.916 337.735 688.582 338.069 688.582 325.5ZM454.5 342.638 450.5 350.638 446.5 342.638Z"
+       id="path29" />
+    <path
+       d="M450.833 45.5 450.833 56.8197 450.167 56.8197 450.167 45.5001ZM454.5 55.4864 450.5 63.4864 446.5 55.4864Z"
+       id="path31" />
+    <path
+       d="M450.833 108.5 450.833 120.375 450.167 120.375 450.167 108.5ZM454.5 119.041 450.5 127.041 446.5 119.041Z"
+       id="path33" />
+    <path
+       d="M451.833 507.5 451.833 533.61 451.167 533.61 451.167 507.5ZM455.5 532.277 451.5 540.277 447.5 532.277Z"
+       id="path35" />
+    <path
+       d="M0 0.333333-23.9993 0.333333-23.666 0-23.666 141.649-23.9993 141.316 562.966 141.316 562.633 141.649 562.633 124.315 563.299 124.315 563.299 141.983-24.3327 141.983-24.3327-0.333333 0-0.333333ZM558.966 125.649 562.966 117.649 566.966 125.649Z"
+       transform="matrix(-6.12323e-17 -1 -1 6.12323e-17 451.149 585.466)"
+       id="path37" />
+    <path
+       d="M333.5 160.5 450.5 126.5 567.5 160.5 450.5 194.5Z"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#D9D9D9"
+       fill-rule="evenodd"
+       id="path39" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="19"
+       transform="translate(417.576 155)"
+       id="text43">add new <tspan
+   font-size="19"
+   x="13.2867"
+   y="23"
+   id="tspan41">rule?</tspan></text>
+    <path
+       d="M567.5 160.167 689.267 160.167 689.267 273.228 688.6 273.228 688.6 160.5 688.933 160.833 567.5 160.833ZM692.933 271.894 688.933 279.894 684.933 271.894Z"
+       id="path45" />
+    <rect
+       x="602.5"
+       y="127.5"
+       width="46"
+       height="30"
+       stroke="#000000"
+       stroke-width="0.666667"
+       stroke-miterlimit="8"
+       fill="#D9D9D9"
+       id="rect47" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="19"
+       transform="translate(611.34 148)"
+       id="text49">yes</text>
+    <rect
+       x="254.5"
+       y="126.5"
+       width="46"
+       height="31"
+       stroke="#000000"
+       stroke-width="0.666667"
+       stroke-miterlimit="8"
+       fill="#D9D9D9"
+       id="rect51" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="19"
+       transform="translate(267.182 147)"
+       id="text53">no</text>
+    <path
+       d="M0-0.333333 251.563-0.333333 251.563 298.328 8.00002 298.328 8.00002 297.662 251.229 297.662 250.896 297.995 250.896 0 251.229 0.333333 0 0.333333ZM9.33333 301.995 1.33333 297.995 9.33333 293.995Z"
+       transform="matrix(1 0 0 -1 567.5 383.495)"
+       id="path55" />
+    <path
+       d="M86.5001 213.5 203.5 180.5 320.5 213.5 203.5 246.5Z"
+       stroke="#000000"
+       stroke-width="1.33333"
+       stroke-miterlimit="8"
+       fill="#D9D9D9"
+       fill-rule="evenodd"
+       id="path57" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="19"
+       transform="translate(159.155 208)"
+       id="text61">destroy the <tspan
+   font-size="19"
+   x="24.0333"
+   y="23"
+   id="tspan59">rule?</tspan></text>
+    <path
+       d="M0-0.333333 131.029-0.333333 131.029 12.9778 130.363 12.9778 130.363 0 130.696 0.333333 0 0.333333ZM134.696 11.6445 130.696 19.6445 126.696 11.6445Z"
+       transform="matrix(-1 1.22465e-16 1.22465e-16 1 334.196 160.5)"
+       id="path63" />
+    <rect
+       x="92.600937"
+       y="280.48242"
+       width="210.14578"
+       height="45.035149"
+       stroke="#000000"
+       stroke-width="1.24464"
+       stroke-miterlimit="8"
+       fill="#ffffff"
+       id="rect65" />
+    <text
+       font-family="Calibri, Calibri_MSFontService, sans-serif"
+       font-weight="400"
+       font-size="19px"
+       id="text67"
+       x="100.2282"
+       y="308">rte_flow_async_destroy()</text>
+    <path
+       d="M0 0.333333-24.0001 0.333333-23.6667 0-23.6667 49.9498-24.0001 49.6165 121.748 49.6165 121.748 59.958 121.082 59.958 121.082 49.9498 121.415 50.2832-24.3334 50.2832-24.3334-0.333333 0-0.333333ZM125.415 58.6247 121.415 66.6247 117.415 58.6247Z"
+       transform="matrix(-1 0 0 1 319.915 213.5)"
+       id="path69" />
+    <path
+       d="M86.5001 213.833 62.5002 213.833 62.8335 213.5 62.8335 383.95 62.5002 383.617 327.511 383.617 327.511 384.283 62.1668 384.283 62.1668 213.167 86.5001 213.167ZM326.178 379.95 334.178 383.95 326.178 387.95Z"
+       id="path71" />
+    <path
+       d="M0-0.333333 12.8273-0.333333 12.8273 252.111 12.494 251.778 18.321 251.778 18.321 252.445 12.1607 252.445 12.1607 0 12.494 0.333333 0 0.333333ZM16.9877 248.111 24.9877 252.111 16.9877 256.111Z"
+       transform="matrix(1.83697e-16 1 1 -1.83697e-16 198.5 325.5)"
+       id="path73" />
+    <rect
+       x="357.15436"
+       y="540.45984"
+       width="183.59026"
+       height="45.08033"
+       stroke="#000000"
+       stroke-width="1.25785"
+       stroke-miterlimit="8"
+       fill="#ffffff"
+       id="rect75" />
+    <text
+       font-family="Calibri, Calibri_MSFontService, sans-serif"
+       font-weight="400"
+       font-size="19px"
+       id="text77"
+       x="393.08301"
+       y="569">rte_flow_pull()</text>
+    <rect
+       x="357.15436"
+       y="462.45984"
+       width="183.59026"
+       height="45.08033"
+       stroke="#000000"
+       stroke-width="1.25785"
+       stroke-miterlimit="8"
+       fill="#ffffff"
+       id="rect79" />
+    <text
+       font-family="Calibri, Calibri_MSFontService, sans-serif"
+       font-weight="400"
+       font-size="19px"
+       id="text81"
+       x="389.19"
+       y="491">rte_flow_push()</text>
+    <path
+       d="M450.833 417.495 451.402 455.999 450.735 456.008 450.167 417.505ZM455.048 454.611 451.167 462.669 447.049 454.729Z"
+       id="path83" />
+    <rect
+       x="0.500053"
+       y="287.5"
+       width="46"
+       height="30"
+       stroke="#000000"
+       stroke-width="0.666667"
+       stroke-miterlimit="8"
+       fill="#D9D9D9"
+       id="rect85" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="19"
+       transform="translate(12.8617 308)"
+       id="text87">no</text>
+    <rect
+       x="357.5"
+       y="223.5"
+       width="47"
+       height="31"
+       stroke="#000000"
+       stroke-width="0.666667"
+       stroke-miterlimit="8"
+       fill="#D9D9D9"
+       id="rect89" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="19"
+       transform="translate(367.001 244)"
+       id="text91">yes</text>
+    <rect
+       x="469.5"
+       y="421.5"
+       width="46"
+       height="30"
+       stroke="#000000"
+       stroke-width="0.666667"
+       stroke-miterlimit="8"
+       fill="#D9D9D9"
+       id="rect93" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="19"
+       transform="translate(481.872 442)"
+       id="text95">no</text>
+    <rect
+       x="832.5"
+       y="223.5"
+       width="46"
+       height="31"
+       stroke="#000000"
+       stroke-width="0.666667"
+       stroke-miterlimit="8"
+       fill="#D9D9D9"
+       id="rect97" />
+    <text
+       font-family="Calibri,Calibri_MSFontService,sans-serif"
+       font-weight="400"
+       font-size="19"
+       transform="translate(841.777 244)"
+       id="text99">yes</text>
+  </g>
+</svg>
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 6cdfea09be..436845717f 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -3624,12 +3624,16 @@ Expected number of resources in an application allows PMD to prepare
 and optimize NIC hardware configuration and memory layout in advance.
 ``rte_flow_configure()`` must be called before any flow rule is created,
 but after an Ethernet device is configured.
+It also creates flow queues for asynchronous flow rules operations via
+queue-based API, see `Asynchronous operations`_ section.
 
 .. code-block:: c
 
    int
    rte_flow_configure(uint16_t port_id,
                       const struct rte_flow_port_attr *port_attr,
+                      uint16_t nb_queue,
+                      const struct rte_flow_queue_attr *queue_attr[],
                       struct rte_flow_error *error);
 
 Information about the number of available resources can be retrieved via
@@ -3640,6 +3644,7 @@ Information about the number of available resources can be retrieved via
    int
    rte_flow_info_get(uint16_t port_id,
                      struct rte_flow_port_info *port_info,
+                     struct rte_flow_queue_info *queue_info,
                      struct rte_flow_error *error);
 
 Flow templates
@@ -3777,6 +3782,125 @@ and pattern and actions templates are created.
 				&actions_templates, nb_actions_templ,
 				&error);
 
+Asynchronous operations
+-----------------------
+
+Flow rules management can be done via special lockless flow management queues.
+- Queue operations are asynchronous and not thread-safe.
+
+- Operations can thus be invoked by the app's datapath,
+  packet processing can continue while queue operations are processed by NIC.
+
+- Number of flow queues is configured at initialization stage.
+
+- Available operation types: rule creation, rule destruction,
+  indirect rule creation, indirect rule destruction, indirect rule update.
+
+- Operations may be reordered within a queue.
+
+- Operations can be postponed and pushed to NIC in batches.
+
+- Results pulling must be done on time to avoid queue overflows.
+
+- User data is returned as part of the result to identify an operation.
+
+- Flow handle is valid once the creation operation is enqueued and must be
+  destroyed even if the operation is not successful and the rule is not inserted.
+
+- Application must wait for the creation operation result before enqueueing
+  the deletion operation to make sure the creation is processed by NIC.
+
+The asynchronous flow rule insertion logic can be broken into two phases.
+
+1. Initialization stage as shown here:
+
+.. _figure_rte_flow_async_init:
+
+.. figure:: img/rte_flow_async_init.*
+
+2. Main loop as presented on a datapath application example:
+
+.. _figure_rte_flow_async_usage:
+
+.. figure:: img/rte_flow_async_usage.*
+
+Enqueue creation operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enqueueing a flow rule creation operation is similar to simple creation.
+
+.. code-block:: c
+
+	struct rte_flow *
+	rte_flow_async_create(uint16_t port_id,
+			      uint32_t queue_id,
+			      const struct rte_flow_q_ops_attr *q_ops_attr,
+			      struct rte_flow_template_table *template_table,
+			      const struct rte_flow_item pattern[],
+			      uint8_t pattern_template_index,
+			      const struct rte_flow_action actions[],
+			      uint8_t actions_template_index,
+			      void *user_data,
+			      struct rte_flow_error *error);
+
+A valid handle in case of success is returned. It must be destroyed later
+by calling ``rte_flow_async_destroy()`` even if the rule is rejected by HW.
+
+Enqueue destruction operation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Enqueueing a flow rule destruction operation is similar to simple destruction.
+
+.. code-block:: c
+
+	int
+	rte_flow_async_destroy(uint16_t port_id,
+			       uint32_t queue_id,
+			       const struct rte_flow_q_ops_attr *q_ops_attr,
+			       struct rte_flow *flow,
+			       void *user_data,
+			       struct rte_flow_error *error);
+
+Push enqueued operations
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pushing all internally stored rules from a queue to the NIC.
+
+.. code-block:: c
+
+	int
+	rte_flow_push(uint16_t port_id,
+		      uint32_t queue_id,
+		      struct rte_flow_error *error);
+
+There is the postpone attribute in the queue operation attributes.
+When it is set, multiple operations can be bulked together and not sent to HW
+right away to save SW/HW interactions and prioritize throughput over latency.
+The application must invoke this function to actually push all outstanding
+operations to HW in this case.
+
+Pull enqueued operations
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Pulling asynchronous operations results.
+
+The application must invoke this function in order to complete asynchronous
+flow rule operations and to receive flow rule operations statuses.
+
+.. code-block:: c
+
+	int
+	rte_flow_pull(uint16_t port_id,
+		      uint32_t queue_id,
+		      struct rte_flow_q_op_res res[],
+		      uint16_t n_res,
+		      struct rte_flow_error *error);
+
+Multiple outstanding operation results can be pulled simultaneously.
+User data may be provided during a flow creation/destruction in order
+to distinguish between multiple operations. User data is returned as part
+of the result to provide a method to detect which operation is completed.
+
 .. _flow_isolated_mode:
 
 Flow isolated mode
diff --git a/doc/guides/rel_notes/release_22_03.rst b/doc/guides/rel_notes/release_22_03.rst
index 7150d06c87..cd495ef40c 100644
--- a/doc/guides/rel_notes/release_22_03.rst
+++ b/doc/guides/rel_notes/release_22_03.rst
@@ -113,6 +113,13 @@ New Features
     ``rte_flow_template_table_destroy``, ``rte_flow_pattern_template_destroy``
     and ``rte_flow_actions_template_destroy``.
 
+* ** Added functions for asynchronous flow rules creation/destruction
+
+  * ethdev: Added ``rte_flow_async_create`` and ``rte_flow_async_destroy`` API
+    to enqueue flow creaion/destruction operations asynchronously as well as
+    ``rte_flow_pull`` to poll and retrieve results of these operations and
+    ``rte_flow_push`` to push all the in-flight	operations to the NIC.
+
 * **Updated AF_XDP PMD**
 
   * Added support for libxdp >=v1.2.2.
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index e9f684eedb..4e7b202522 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -1396,6 +1396,7 @@ rte_flow_flex_item_release(uint16_t port_id,
 int
 rte_flow_info_get(uint16_t port_id,
 		  struct rte_flow_port_info *port_info,
+		  struct rte_flow_queue_info *queue_info,
 		  struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
@@ -1415,7 +1416,7 @@ rte_flow_info_get(uint16_t port_id,
 		return -rte_errno;
 	if (likely(!!ops->info_get)) {
 		return flow_err(port_id,
-				ops->info_get(dev, port_info, error),
+				ops->info_get(dev, port_info, queue_info, error),
 				error);
 	}
 	return rte_flow_error_set(error, ENOTSUP,
@@ -1426,6 +1427,8 @@ rte_flow_info_get(uint16_t port_id,
 int
 rte_flow_configure(uint16_t port_id,
 		   const struct rte_flow_port_attr *port_attr,
+		   uint16_t nb_queue,
+		   const struct rte_flow_queue_attr *queue_attr[],
 		   struct rte_flow_error *error)
 {
 	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
@@ -1433,7 +1436,7 @@ rte_flow_configure(uint16_t port_id,
 	int ret;
 
 	dev->data->flow_configured = 0;
-	if (port_attr == NULL) {
+	if (port_attr == NULL || queue_attr == NULL) {
 		RTE_FLOW_LOG(ERR, "Port %"PRIu16" info is NULL.\n", port_id);
 		return -EINVAL;
 	}
@@ -1452,7 +1455,7 @@ rte_flow_configure(uint16_t port_id,
 	if (unlikely(!ops))
 		return -rte_errno;
 	if (likely(!!ops->configure)) {
-		ret = ops->configure(dev, port_attr, error);
+		ret = ops->configure(dev, port_attr, nb_queue, queue_attr, error);
 		if (ret == 0)
 			dev->data->flow_configured = 1;
 		return flow_err(port_id, ret, error);
@@ -1713,3 +1716,104 @@ rte_flow_template_table_destroy(uint16_t port_id,
 				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
 				  NULL, rte_strerror(ENOTSUP));
 }
+
+struct rte_flow *
+rte_flow_async_create(uint16_t port_id,
+		      uint32_t queue_id,
+		      const struct rte_flow_q_ops_attr *q_ops_attr,
+		      struct rte_flow_template_table *template_table,
+		      const struct rte_flow_item pattern[],
+		      uint8_t pattern_template_index,
+		      const struct rte_flow_action actions[],
+		      uint8_t actions_template_index,
+		      void *user_data,
+		      struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+	struct rte_flow *flow;
+
+	if (unlikely(!ops))
+		return NULL;
+	if (likely(!!ops->async_create)) {
+		flow = ops->async_create(dev, queue_id,
+					 q_ops_attr, template_table,
+					 pattern, pattern_template_index,
+					 actions, actions_template_index,
+					 user_data, error);
+		if (flow == NULL)
+			flow_err(port_id, -rte_errno, error);
+		return flow;
+	}
+	rte_flow_error_set(error, ENOTSUP,
+			   RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+			   NULL, rte_strerror(ENOTSUP));
+	return NULL;
+}
+
+int
+rte_flow_async_destroy(uint16_t port_id,
+		       uint32_t queue_id,
+		       const struct rte_flow_q_ops_attr *q_ops_attr,
+		       struct rte_flow *flow,
+		       void *user_data,
+		       struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+
+	if (unlikely(!ops))
+		return -rte_errno;
+	if (likely(!!ops->async_destroy)) {
+		return flow_err(port_id,
+				ops->async_destroy(dev, queue_id,
+						   q_ops_attr, flow,
+						   user_data, error),
+				error);
+	}
+	return rte_flow_error_set(error, ENOTSUP,
+				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				  NULL, rte_strerror(ENOTSUP));
+}
+
+int
+rte_flow_push(uint16_t port_id,
+	      uint32_t queue_id,
+	      struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+
+	if (unlikely(!ops))
+		return -rte_errno;
+	if (likely(!!ops->push)) {
+		return flow_err(port_id,
+				ops->push(dev, queue_id, error),
+				error);
+	}
+	return rte_flow_error_set(error, ENOTSUP,
+				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				  NULL, rte_strerror(ENOTSUP));
+}
+
+int
+rte_flow_pull(uint16_t port_id,
+	      uint32_t queue_id,
+	      struct rte_flow_q_op_res res[],
+	      uint16_t n_res,
+	      struct rte_flow_error *error)
+{
+	struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+	const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+	int ret;
+
+	if (unlikely(!ops))
+		return -rte_errno;
+	if (likely(!!ops->pull)) {
+		ret = ops->pull(dev, queue_id, res, n_res, error);
+		return ret ? ret : flow_err(port_id, ret, error);
+	}
+	return rte_flow_error_set(error, ENOTSUP,
+				  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+				  NULL, rte_strerror(ENOTSUP));
+}
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index 776e8ccc11..9e71a576f6 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -4884,6 +4884,10 @@ rte_flow_flex_item_release(uint16_t port_id,
  *
  */
 struct rte_flow_port_info {
+	/**
+	 * Maximum umber of queues for asynchronous operations.
+	 */
+	uint32_t max_nb_queues;
 	/**
 	 * Maximum number of counters.
 	 * @see RTE_FLOW_ACTION_TYPE_COUNT
@@ -4901,6 +4905,21 @@ struct rte_flow_port_info {
 	uint32_t max_nb_meters;
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Information about flow engine asynchronous queues.
+ * The value only valid if @p port_attr.max_nb_queues is not zero.
+ *
+ */
+struct rte_flow_queue_info {
+	/**
+	 * Maximum number of operations a queue can hold.
+	 */
+	uint32_t max_size;
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -4912,6 +4931,9 @@ struct rte_flow_port_info {
  * @param[out] port_info
  *   A pointer to a structure of type *rte_flow_port_info*
  *   to be filled with the resources information of the port.
+ * @param[out] queue_info
+ *   A pointer to a structure of type *rte_flow_queue_info*
+ *   to be filled with the asynchronous queues information.
  * @param[out] error
  *   Perform verbose error reporting if not NULL.
  *   PMDs initialize this structure in case of error only.
@@ -4923,6 +4945,7 @@ __rte_experimental
 int
 rte_flow_info_get(uint16_t port_id,
 		  struct rte_flow_port_info *port_info,
+		  struct rte_flow_queue_info *queue_info,
 		  struct rte_flow_error *error);
 
 /**
@@ -4951,6 +4974,21 @@ struct rte_flow_port_attr {
 	uint32_t nb_meters;
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Flow engine asynchronous queues settings.
+ * The value means default value picked by PMD.
+ *
+ */
+struct rte_flow_queue_attr {
+	/**
+	 * Number of flow rule operations a queue can hold.
+	 */
+	uint32_t size;
+};
+
 /**
  * @warning
  * @b EXPERIMENTAL: this API may change without prior notice.
@@ -4970,6 +5008,11 @@ struct rte_flow_port_attr {
  *   Port identifier of Ethernet device.
  * @param[in] port_attr
  *   Port configuration attributes.
+ * @param[in] nb_queue
+ *   Number of flow queues to be configured.
+ * @param[in] queue_attr
+ *   Array that holds attributes for each flow queue.
+ *   Number of elements is set in @p port_attr.nb_queues.
  * @param[out] error
  *   Perform verbose error reporting if not NULL.
  *   PMDs initialize this structure in case of error only.
@@ -4981,6 +5024,8 @@ __rte_experimental
 int
 rte_flow_configure(uint16_t port_id,
 		   const struct rte_flow_port_attr *port_attr,
+		   uint16_t nb_queue,
+		   const struct rte_flow_queue_attr *queue_attr[],
 		   struct rte_flow_error *error);
 
 /**
@@ -5257,6 +5302,212 @@ rte_flow_template_table_destroy(uint16_t port_id,
 		struct rte_flow_template_table *template_table,
 		struct rte_flow_error *error);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Queue operation attributes.
+ */
+__extension__
+struct rte_flow_q_ops_attr {
+	 /**
+	  * When set, the requested action will not be sent to the HW immediately.
+	  * The application must call the rte_flow_queue_push to actually send it.
+	  */
+	uint32_t postpone:1;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue rule creation operation.
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param queue_id
+ *   Flow queue used to insert the rule.
+ * @param[in] q_ops_attr
+ *   Rule creation operation attributes.
+ * @param[in] template_table
+ *   Template table to select templates from.
+ * @param[in] pattern
+ *   List of pattern items to be used.
+ *   The list order should match the order in the pattern template.
+ *   The spec is the only relevant member of the item that is being used.
+ * @param[in] pattern_template_index
+ *   Pattern template index in the table.
+ * @param[in] actions
+ *   List of actions to be used.
+ *   The list order should match the order in the actions template.
+ * @param[in] actions_template_index
+ *   Actions template index in the table.
+ * @param[in] user_data
+ *   The user data that will be returned on the completion events.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *   PMDs initialize this structure in case of error only.
+ *
+ * @return
+ *   Handle on success, NULL otherwise and rte_errno is set.
+ *   The rule handle doesn't mean that the rule has been populated.
+ *   Only completion result indicates that if there was success or failure.
+ */
+__rte_experimental
+struct rte_flow *
+rte_flow_async_create(uint16_t port_id,
+		      uint32_t queue_id,
+		      const struct rte_flow_q_ops_attr *q_ops_attr,
+		      struct rte_flow_template_table *template_table,
+		      const struct rte_flow_item pattern[],
+		      uint8_t pattern_template_index,
+		      const struct rte_flow_action actions[],
+		      uint8_t actions_template_index,
+		      void *user_data,
+		      struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Enqueue rule destruction operation.
+ *
+ * This function enqueues a destruction operation on the queue.
+ * Application should assume that after calling this function
+ * the rule handle is not valid anymore.
+ * Completion indicates the full removal of the rule from the HW.
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param queue_id
+ *   Flow queue which is used to destroy the rule.
+ *   This must match the queue on which the rule was created.
+ * @param[in] q_ops_attr
+ *   Rule destroy operation attributes.
+ * @param[in] flow
+ *   Flow handle to be destroyed.
+ * @param[in] user_data
+ *   The user data that will be returned on the completion events.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *   PMDs initialize this structure in case of error only.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+__rte_experimental
+int
+rte_flow_async_destroy(uint16_t port_id,
+		       uint32_t queue_id,
+		       const struct rte_flow_q_ops_attr *q_ops_attr,
+		       struct rte_flow *flow,
+		       void *user_data,
+		       struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Push all internally stored rules to the HW.
+ * Postponed rules are rules that were inserted with the postpone flag set.
+ * Can be used to notify the HW about batch of rules prepared by the SW to
+ * reduce the number of communications between the HW and SW.
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param queue_id
+ *   Flow queue to be pushed.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *   PMDs initialize this structure in case of error only.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set
+ *   to one of the error codes defined:
+ *   - (ENODEV) if *port_id* invalid.
+ *   - (ENOSYS) if underlying device does not support this functionality.
+ *   - (EIO) if underlying device is removed.
+ *   - (EINVAL) if *queue_id* invalid.
+ */
+__rte_experimental
+int
+rte_flow_push(uint16_t port_id,
+	      uint32_t queue_id,
+	      struct rte_flow_error *error);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Queue operation status.
+ */
+enum rte_flow_q_op_status {
+	/**
+	 * The operation was completed successfully.
+	 */
+	RTE_FLOW_Q_OP_SUCCESS,
+	/**
+	 * The operation was not completed successfully.
+	 */
+	RTE_FLOW_Q_OP_ERROR,
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Queue operation results.
+ */
+__extension__
+struct rte_flow_q_op_res {
+	/**
+	 * Returns the status of the operation that this completion signals.
+	 */
+	enum rte_flow_q_op_status status;
+	/**
+	 * The user data that will be returned on the completion events.
+	 */
+	void *user_data;
+};
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice.
+ *
+ * Pull a rte flow operation.
+ * The application must invoke this function in order to complete
+ * the flow rule offloading and to retrieve the flow rule operation status.
+ *
+ * @param port_id
+ *   Port identifier of Ethernet device.
+ * @param queue_id
+ *   Flow queue which is used to pull the operation.
+ * @param[out] res
+ *   Array of results that will be set.
+ * @param[in] n_res
+ *   Maximum number of results that can be returned.
+ *   This value is equal to the size of the res array.
+ * @param[out] error
+ *   Perform verbose error reporting if not NULL.
+ *   PMDs initialize this structure in case of error only.
+ *
+ * @return
+ *   Number of results that were pulled,
+ *   a negative errno value otherwise and rte_errno is set
+ *   to one of the error codes defined:
+ *   - (ENODEV) if *port_id* invalid.
+ *   - (ENOSYS) if underlying device does not support this functionality.
+ *   - (EIO) if underlying device is removed.
+ *   - (EINVAL) if *queue_id* invalid.
+ */
+__rte_experimental
+int
+rte_flow_pull(uint16_t port_id,
+	      uint32_t queue_id,
+	      struct rte_flow_q_op_res res[],
+	      uint16_t n_res,
+	      struct rte_flow_error *error);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ethdev/rte_flow_driver.h b/lib/ethdev/rte_flow_driver.h
index 2d96db1dc7..332783cf78 100644
--- a/lib/ethdev/rte_flow_driver.h
+++ b/lib/ethdev/rte_flow_driver.h
@@ -156,11 +156,14 @@ struct rte_flow_ops {
 	int (*info_get)
 		(struct rte_eth_dev *dev,
 		 struct rte_flow_port_info *port_info,
+		 struct rte_flow_queue_info *queue_info,
 		 struct rte_flow_error *err);
 	/** See rte_flow_configure() */
 	int (*configure)
 		(struct rte_eth_dev *dev,
 		 const struct rte_flow_port_attr *port_attr,
+		 uint16_t nb_queue,
+		 const struct rte_flow_queue_attr *queue_attr[],
 		 struct rte_flow_error *err);
 	/** See rte_flow_pattern_template_create() */
 	struct rte_flow_pattern_template *(*pattern_template_create)
@@ -199,6 +202,38 @@ struct rte_flow_ops {
 		(struct rte_eth_dev *dev,
 		 struct rte_flow_template_table *template_table,
 		 struct rte_flow_error *err);
+	/** See rte_flow_async_create() */
+	struct rte_flow *(*async_create)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 const struct rte_flow_q_ops_attr *q_ops_attr,
+		 struct rte_flow_template_table *template_table,
+		 const struct rte_flow_item pattern[],
+		 uint8_t pattern_template_index,
+		 const struct rte_flow_action actions[],
+		 uint8_t actions_template_index,
+		 void *user_data,
+		 struct rte_flow_error *err);
+	/** See rte_flow_async_destroy() */
+	int (*async_destroy)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 const struct rte_flow_q_ops_attr *q_ops_attr,
+		 struct rte_flow *flow,
+		 void *user_data,
+		 struct rte_flow_error *err);
+	/** See rte_flow_push() */
+	int (*push)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 struct rte_flow_error *err);
+	/** See rte_flow_pull() */
+	int (*pull)
+		(struct rte_eth_dev *dev,
+		 uint32_t queue_id,
+		 struct rte_flow_q_op_res res[],
+		 uint16_t n_res,
+		 struct rte_flow_error *error);
 };
 
 /**
diff --git a/lib/ethdev/version.map b/lib/ethdev/version.map
index 62ff791261..13c1a22118 100644
--- a/lib/ethdev/version.map
+++ b/lib/ethdev/version.map
@@ -272,6 +272,10 @@ EXPERIMENTAL {
 	rte_flow_actions_template_destroy;
 	rte_flow_template_table_create;
 	rte_flow_template_table_destroy;
+	rte_flow_async_create;
+	rte_flow_async_destroy;
+	rte_flow_push;
+	rte_flow_pull;
 };
 
 INTERNAL {
