diff --git a/oslo_concurrency/processutils.py b/oslo_concurrency/processutils.py
index 78f8f14..9892aba 100644
--- a/oslo_concurrency/processutils.py
+++ b/oslo_concurrency/processutils.py
@@ -189,7 +189,12 @@ def execute(*cmd, **kwargs):
             raise NoRootWrapSpecified(
                 message=_('Command requested root, but did not '
                           'specify a root helper.'))
-        cmd = shlex.split(root_helper) + list(cmd)
+        if shell:
+            # root helper has to be injected into the command string
+            cmd = [' '.join((root_helper, cmd[0]))] + list(cmd[1:])
+        else:
+            # root helper has to be tokenized into argument list
+            cmd = shlex.split(root_helper) + list(cmd)
 
     cmd = [str(c) for c in cmd]
     sanitized_cmd = strutils.mask_password(' '.join(cmd))
diff --git a/tests/test_processutils.py b/tests/test_processutils.py
index ca15385..dfc24cc 100644
--- a/tests/test_processutils.py
+++ b/tests/test_processutils.py
@@ -298,6 +298,18 @@ grep foo
 
         self.assertIn('SUPER_UNIQUE_VAR=The answer is 42', out)
 
+    def test_as_root(self):
+        out, err = processutils.execute('a', 'b', 'c', run_as_root=True,
+                                        root_helper='echo')
+
+        self.assertIn('a b c', six.text_type(out))
+
+    def test_as_root_via_shell(self):
+        out, err = processutils.execute('a b c', run_as_root=True,
+                                        root_helper='echo', shell=True)
+
+        self.assertIn('a b c', six.text_type(out))
+
     def test_exception_and_masking(self):
         tmpfilename = self.create_tempfiles(
             [["test_exceptions_and_masking",