diff --git a/kayobe/kolla_ansible.py b/kayobe/kolla_ansible.py
index 6eed88237abf433300765b1c9a3731c6ec62a6b3..8c5532b82aebe693a93cb83fdcb231a9acbe6239 100644
--- a/kayobe/kolla_ansible.py
+++ b/kayobe/kolla_ansible.py
@@ -56,6 +56,8 @@ def add_args(parser):
     parser.add_argument("-kl", "--kolla-limit", metavar="SUBSET",
                         help="further limit selected hosts to an additional "
                              "pattern")
+    parser.add_argument("-kp", "--kolla-playbook", metavar="PLAYBOOK",
+                        help="path to Ansible playbook file")
     parser.add_argument("--kolla-skip-tags", metavar="TAGS",
                         help="only run plays and tasks whose tags do not "
                              "match these values in Kolla Ansible")
@@ -104,6 +106,13 @@ def _validate_args(parsed_args, inventory_filename):
                   parsed_args.kolla_venv, result["message"])
         sys.exit(1)
 
+    if parsed_args.kolla_playbook:
+        result = utils.is_readable_file(parsed_args.kolla_playbook)
+        if not result["result"]:
+            LOG.error("Kolla Ansible playbook %s is invalid: %s",
+                      parsed_args.kolla_playbook, result["message"])
+            sys.exit(1)
+
 
 def build_args(parsed_args, command, inventory_filename, extra_vars=None,
                tags=None, verbose_level=None, extra_args=None, limit=None):
@@ -113,6 +122,8 @@ def build_args(parsed_args, command, inventory_filename, extra_vars=None,
     cmd += ["kolla-ansible", command]
     if verbose_level:
         cmd += ["-" + "v" * verbose_level]
+    if parsed_args.kolla_playbook:
+        cmd += ["--playbook", parsed_args.kolla_playbook]
     cmd += vault.build_args(parsed_args, "--key")
     inventory = _get_inventory_path(parsed_args, inventory_filename)
     cmd += ["--inventory", inventory]
diff --git a/kayobe/tests/unit/test_kolla_ansible.py b/kayobe/tests/unit/test_kolla_ansible.py
index 6ab0dcd4299b8f8848a52aec974f8ed55da5068c..8f965067268d2c5b0027b6566fec91d41b55a3a7 100644
--- a/kayobe/tests/unit/test_kolla_ansible.py
+++ b/kayobe/tests/unit/test_kolla_ansible.py
@@ -61,12 +61,14 @@ class TestCase(unittest.TestCase):
             "-ki", "/path/to/inventory",
             "-kl", "host1:host2",
             "-kt", "tag1,tag2",
+            "-kp", "/path/to/playbook",
         ]
         parsed_args = parser.parse_args(args)
         kolla_ansible.run(parsed_args, "command", "overcloud")
         expected_cmd = [
             ".", "/path/to/cwd/venvs/kolla-ansible/bin/activate", "&&",
             "kolla-ansible", "command",
+            "--playbook", "/path/to/playbook",
             "--inventory", "/path/to/inventory",
             "--configdir", "/path/to/config",
             "--passwords", "/path/to/config/passwords.yml",
@@ -98,6 +100,7 @@ class TestCase(unittest.TestCase):
             "--kolla-limit", "host1:host2",
             "--kolla-skip-tags", "tag3,tag4",
             "--kolla-tags", "tag1,tag2",
+            "--kolla-playbook", "/path/to/playbook",
         ]
         parsed_args = parser.parse_args(args)
         mock_run.return_value = "/path/to/kayobe-vault-password-helper"
@@ -105,6 +108,7 @@ class TestCase(unittest.TestCase):
         expected_cmd = [
             ".", "/path/to/cwd/venvs/kolla-ansible/bin/activate", "&&",
             "kolla-ansible", "command",
+            "--playbook", "/path/to/playbook",
             "--key", "/path/to/kayobe-vault-password-helper",
             "--inventory", "/path/to/inventory",
             "--configdir", "/path/to/config",
diff --git a/releasenotes/notes/kolla-ansible-playbook-7e4418ca757e81e8.yaml b/releasenotes/notes/kolla-ansible-playbook-7e4418ca757e81e8.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..77d3f0772c8f388ed240fc54409f9c8b5b8e691e
--- /dev/null
+++ b/releasenotes/notes/kolla-ansible-playbook-7e4418ca757e81e8.yaml
@@ -0,0 +1,12 @@
+---
+features:
+  - |
+    Adds support for specifying a custom playbook when running Kolla Ansible
+    commands via a ``--kolla-playbook`` argument. For example:
+
+    .. code-block:: console
+
+       kayobe overcloud service deploy --kolla-playbook /path/to/playbook.yml
+
+    This may be used to specify a playbook that replaces or extends the default
+    ``site.yml`` playbook, and needs to execute in the Kolla Ansible context.