diff --git a/roles/ipaclient/library/ipaclient_join.py b/roles/ipaclient/library/ipaclient_join.py
index a11f3f257421500a4eccee4fa81163ace0ab4efc..7057b5f6959d9908879a9cf951809b693e5c6b47 100644
--- a/roles/ipaclient/library/ipaclient_join.py
+++ b/roles/ipaclient/library/ipaclient_join.py
@@ -60,6 +60,9 @@ options:
   password:
     description: The password to use if not using Kerberos to authenticate.
     required: false
+  admin_keytab:
+    description: The path to a local admin keytab.
+    required: false
   keytab:
     description: The path to a backed-up host keytab from previous enrollment.
     required: false
@@ -138,6 +141,7 @@ def main():
             principal=dict(required=False),
             password=dict(required=False, no_log=True),
             keytab=dict(required=False),
+            admin_keytab=dict(required=False),
             ca_cert_file=dict(required=False),
             force_join=dict(required=False, type='bool'),
             kinit_attempts=dict(required=False, type='int', default=5),
@@ -157,6 +161,7 @@ def main():
     principal = module.params.get('principal')
     password = module.params.get('password')
     keytab = module.params.get('keytab')
+    admin_keytab = module.params.get('admin_keytab')
     ca_cert_file = module.params.get('ca_cert_file')
     kinit_attempts = module.params.get('kinit_attempts')
     debug = module.params.get('debug')
@@ -164,6 +169,9 @@ def main():
     if password is not None and keytab is not None:
         module.fail_json(msg="Password and keytab cannot be used together")
 
+    if password is None and admin_keytab is None:
+        module.fail_json(msg="Password or admin_keytab is needed")
+
     client_domain = hostname[hostname.find(".")+1:]
     nolog = tuple()
     env = {'PATH': SECURE_PATH}
@@ -209,12 +217,29 @@ def main():
         if principal is not None:
             if principal.find('@') == -1:
                 principal = '%s@%s' % (principal, realm)
-            try:
-                kinit_password(principal, password, ccache_name,
-                               config=krb_name)
-            except RuntimeError as e:
-                module.fail_json(
-                    msg="Kerberos authentication failed: {}".format(e))
+            if admin_keytab:
+                join_args.append("-f")
+                if not os.path.exists(admin_keytab):
+                    module.fail_json(
+                        msg="Keytab file could not be found: %s" % \
+                        admin_keytab)
+                try:
+                    kinit_keytab(principal,
+                                 admin_keytab,
+                                 ccache_name,
+                                 config=krb_name,
+                                 attempts=kinit_attempts)
+                except GSSError as e:
+                    module.fail_json(
+                        msg="Kerberos authentication failed: %s" % str(e))
+            else:
+                try:
+                    kinit_password(principal, password, ccache_name,
+                                   config=krb_name)
+                except RuntimeError as e:
+                    module.fail_json(
+                        msg="Kerberos authentication failed: {}".format(e))
+
         elif keytab:
             join_args.append("-f")
             if os.path.exists(keytab):
diff --git a/roles/ipaclient/tasks/install.yml b/roles/ipaclient/tasks/install.yml
index 74b3ea1450a481069aac0666931a429836493bbf..72864fe394ec2d4793b27aef4797304744ef30a2 100644
--- a/roles/ipaclient/tasks/install.yml
+++ b/roles/ipaclient/tasks/install.yml
@@ -156,6 +156,7 @@
       fail: msg="At least one of password or keytabs must be specified"
       when: not result_ipaclient_test_keytab.krb5_keytab_ok
             and ipaadmin_password is undefined
+            and ipaadmin_keytab is undefined
             and ipaclient_keytab is undefined
     when: not ipaclient_on_master | bool
 
@@ -190,6 +191,7 @@
                      ipaclient_keytab is not defined else omit }}"
       password: "{{ ipaadmin_password | default(omit) }}"
       keytab: "{{ ipaclient_keytab | default(omit) }}"
+      admin_keytab: "{{ ipaadmin_keytab if not ipaclient_use_otp | bool and ipaadmin_keytab else omit }}"
       # ca_cert_file: "{{ ipaclient_ca_cert_file | default(omit) }}"
       kinit_attempts: "{{ ipaclient_kinit_attempts | default(omit) }}"
     register: result_ipaclient_join