diff --git a/ansible/roles/openvswitch/defaults/main.yml b/ansible/roles/openvswitch/defaults/main.yml
index ba765f04994924b691efbbab8c94375cd577a8ac..06b1e566ef91994f87faaf35726557daa3187cd4 100644
--- a/ansible/roles/openvswitch/defaults/main.yml
+++ b/ansible/roles/openvswitch/defaults/main.yml
@@ -96,6 +96,8 @@ openvswitch_extra_volumes: "{{ default_extra_volumes }}"
 openvswitch_db_extra_volumes: "{{ openvswitch_extra_volumes }}"
 openvswitch_vswitchd_extra_volumes: "{{ openvswitch_extra_volumes }}"
 
+openvswitch_ovs_vsctl_wrapper_enabled: false
+
 #############
 # OpenvSwitch
 #############
diff --git a/ansible/roles/openvswitch/tasks/config.yml b/ansible/roles/openvswitch/tasks/config.yml
index 4089234fe5c538d035e4d4994b68979537f0fc33..56507617fe14f2b4264f5d3ef4f8a8ffbc15da9b 100644
--- a/ansible/roles/openvswitch/tasks/config.yml
+++ b/ansible/roles/openvswitch/tasks/config.yml
@@ -52,3 +52,16 @@
     - service.enabled | bool
   notify:
     - "Restart openvswitch-db-server container"
+
+- name: Copying over ovs-vsctl wrapper
+  vars:
+    service: "{{ openvswitch_services['openvswitch-vswitchd'] }}"
+  template:
+    src: "ovs-vsctl.j2"
+    dest: "/usr/bin/ovs-vsctl"
+    mode: "0755"
+  become: true
+  when:
+    - service.host_in_groups | bool
+    - service.enabled | bool
+    - openvswitch_ovs_vsctl_wrapper_enabled | bool
diff --git a/ansible/roles/openvswitch/templates/ovs-vsctl.j2 b/ansible/roles/openvswitch/templates/ovs-vsctl.j2
new file mode 100644
index 0000000000000000000000000000000000000000..85f7f42ee21ce856a5b3ad5ced30eff55de122ab
--- /dev/null
+++ b/ansible/roles/openvswitch/templates/ovs-vsctl.j2
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+exec docker exec openvswitch_vswitchd ovs-vsctl "$@"
diff --git a/doc/source/reference/compute/libvirt-guide.rst b/doc/source/reference/compute/libvirt-guide.rst
index 690d6bce44d17a4fe3936aa5cec3de55cd044f82..013210c04345d57d6ff63bcc09776ce1c393b337 100644
--- a/doc/source/reference/compute/libvirt-guide.rst
+++ b/doc/source/reference/compute/libvirt-guide.rst
@@ -54,6 +54,23 @@ libvirt as a host daemon. However, since the Yoga release, if a libvirt daemon
 has already been set up, then Kolla Ansible may be configured to use it. This
 may be achieved by setting ``enable_nova_libvirt_container`` to ``false``.
 
+When the firewall driver is set to ``openvswitch``, libvirt will plug VMs
+directly into the integration bridge, ``br-int``. To do this it uses the
+``ovs-vsctl`` utility. The search path for this binary is controlled by the
+``$PATH`` environment variable (as seen by the libvirt process). There are a
+few options to ensure that this binary can be found:
+
+* Set ``openvswitch_ovs_vsctl_wrapper_enabled`` to ``True``. This will install
+  a wrapper script to the path: ``/usr/bin/ovs-vsctl`` that will execute
+  ``ovs-vsctl`` in the context of the ``openvswitch_vswitchd`` container. This
+  option is useful if you do not have openvswitch installed on the host. It
+  also has the advantage that the ``ovs-vsctl`` utility will match the version
+  of the server.
+
+* Install openvswitch on the hypervisor. Kolla mounts ``/run/openvswitch`` from
+  the host into the ``openvswitch_vswitchd`` container. This means that socket
+  is in the location ``ovs-vsctl`` expects with its default options.
+
 Migration from container to host
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/releasenotes/notes/adds-ovs-vsctl-wrapper-da3dbbb19d5cc6f5.yaml b/releasenotes/notes/adds-ovs-vsctl-wrapper-da3dbbb19d5cc6f5.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..56c4a16593e3c3261e3c408636af333ef9fc1dc0
--- /dev/null
+++ b/releasenotes/notes/adds-ovs-vsctl-wrapper-da3dbbb19d5cc6f5.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Adds a new flag, ``openvswitch_ovs_vsctl_wrapper_enabled`` which will
+    install a wrapper script to ``/usr/bin/ovs-vsctl`` to docker exec into
+    the openvswitchd container.