diff --git a/common/djangoapps/student/tests/tests.py b/common/djangoapps/student/tests/tests.py
index f788c7fd3d55d5c445db40533246150a4cd15737..acd150766fc3ba0197ff426ccca9ccd2a26cdf69 100644
--- a/common/djangoapps/student/tests/tests.py
+++ b/common/djangoapps/student/tests/tests.py
@@ -157,38 +157,43 @@ class CourseEndingTest(TestCase):
                          {'status': 'processing',
                           'show_disabled_download_button': False,
                           'show_download_url': False,
-                          'show_survey_button': False, })
+                          'show_survey_button': False,
+                          })
 
         cert_status = {'status': 'unavailable'}
         self.assertEqual(_cert_info(user, course, cert_status),
                          {'status': 'processing',
                           'show_disabled_download_button': False,
                           'show_download_url': False,
-                          'show_survey_button': False})
+                          'show_survey_button': False,
+                          'mode': None
+                          })
 
-        cert_status = {'status': 'generating', 'grade': '67'}
+        cert_status = {'status': 'generating', 'grade': '67', 'mode': 'honor'}
         self.assertEqual(_cert_info(user, course, cert_status),
                          {'status': 'generating',
                           'show_disabled_download_button': True,
                           'show_download_url': False,
                           'show_survey_button': True,
                           'survey_url': survey_url,
-                          'grade': '67'
+                          'grade': '67',
+                          'mode': 'honor'
                           })
 
-        cert_status = {'status': 'regenerating', 'grade': '67'}
+        cert_status = {'status': 'regenerating', 'grade': '67', 'mode': 'verified'}
         self.assertEqual(_cert_info(user, course, cert_status),
                          {'status': 'generating',
                           'show_disabled_download_button': True,
                           'show_download_url': False,
                           'show_survey_button': True,
                           'survey_url': survey_url,
-                          'grade': '67'
+                          'grade': '67',
+                          'mode': 'verified'
                           })
 
         download_url = 'http://s3.edx/cert'
         cert_status = {'status': 'downloadable', 'grade': '67',
-                       'download_url': download_url}
+                       'download_url': download_url, 'mode': 'honor'}
         self.assertEqual(_cert_info(user, course, cert_status),
                          {'status': 'ready',
                           'show_disabled_download_button': False,
@@ -196,30 +201,33 @@ class CourseEndingTest(TestCase):
                           'download_url': download_url,
                           'show_survey_button': True,
                           'survey_url': survey_url,
-                          'grade': '67'
+                          'grade': '67',
+                          'mode': 'honor'
                           })
 
         cert_status = {'status': 'notpassing', 'grade': '67',
-                       'download_url': download_url}
+                       'download_url': download_url, 'mode': 'honor'}
         self.assertEqual(_cert_info(user, course, cert_status),
                          {'status': 'notpassing',
                           'show_disabled_download_button': False,
                           'show_download_url': False,
                           'show_survey_button': True,
                           'survey_url': survey_url,
-                          'grade': '67'
+                          'grade': '67',
+                          'mode': 'honor'
                           })
 
         # Test a course that doesn't have a survey specified
         course2 = Mock(end_of_course_survey_url=None)
         cert_status = {'status': 'notpassing', 'grade': '67',
-                       'download_url': download_url}
+                       'download_url': download_url, 'mode': 'honor'}
         self.assertEqual(_cert_info(user, course2, cert_status),
                          {'status': 'notpassing',
                           'show_disabled_download_button': False,
                           'show_download_url': False,
                           'show_survey_button': False,
-                          'grade': '67'
+                          'grade': '67',
+                          'mode': 'honor'
                           })
 
 
diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index 1702d7145e8371f96d19b356313bd2c9fb82f964..81aa8595630481d4b4f7fa750e19d331e83d23bb 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -185,7 +185,8 @@ def _cert_info(user, course, cert_status):
     default_info = {'status': default_status,
                     'show_disabled_download_button': False,
                     'show_download_url': False,
-                    'show_survey_button': False}
+                    'show_survey_button': False,
+                    }
 
     if cert_status is None:
         return default_info
@@ -203,7 +204,8 @@ def _cert_info(user, course, cert_status):
 
     d = {'status': status,
          'show_download_url': status == 'ready',
-         'show_disabled_download_button': status == 'generating', }
+         'show_disabled_download_button': status == 'generating',
+         'mode': cert_status.get('mode', None)}
 
     if (status in ('generating', 'ready', 'notpassing', 'restricted') and
             course.end_of_course_survey_url is not None):
@@ -296,7 +298,7 @@ def complete_course_mode_info(course_id, enrollment):
 def dashboard(request):
     user = request.user
 
-    # Build our (course, enorllment) list for the user, but ignore any courses that no 
+    # Build our (course, enrollment) list for the user, but ignore any courses that no
     # longer exist (because the course IDs have changed). Still, we don't delete those
     # enrollments, because it could have been a data push snafu.
     course_enrollment_pairs = []
@@ -1512,4 +1514,4 @@ def change_email_settings(request):
         log.info(u"User {0} ({1}) opted out of receiving emails from course {2}".format(user.username, user.email, course_id))
         track.views.server_track(request, "change-email-settings", {"receive_emails": "no", "course": course_id}, page='dashboard')
 
-    return HttpResponse(json.dumps({'success': True}))
\ No newline at end of file
+    return HttpResponse(json.dumps({'success': True}))
diff --git a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py
index 5fb9c53718c3580b370954013a1ce8544a4042e3..5aa223acabb581ab33c5c35d0fbb91f120c21370 100644
--- a/lms/djangoapps/certificates/management/commands/ungenerated_certs.py
+++ b/lms/djangoapps/certificates/management/commands/ungenerated_certs.py
@@ -93,6 +93,7 @@ class Command(BaseCommand):
             total = enrolled_students.count()
             count = 0
             start = datetime.datetime.now(UTC)
+
             for student in enrolled_students:
                 count += 1
                 if count % STATUS_INTERVAL == 0:
diff --git a/lms/djangoapps/certificates/migrations/0015_adding_mode_for_verified_certs.py b/lms/djangoapps/certificates/migrations/0015_adding_mode_for_verified_certs.py
new file mode 100644
index 0000000000000000000000000000000000000000..c16d51b8ee4e73d036a5a550ba23bc0e1584f381
--- /dev/null
+++ b/lms/djangoapps/certificates/migrations/0015_adding_mode_for_verified_certs.py
@@ -0,0 +1,86 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+    def forwards(self, orm):
+        # Adding field 'GeneratedCertificate.mode'
+        db.add_column('certificates_generatedcertificate', 'mode',
+                      self.gf('django.db.models.fields.CharField')(default='honor', max_length=32),
+                      keep_default=False)
+
+
+    def backwards(self, orm):
+        # Deleting field 'GeneratedCertificate.mode'
+        db.delete_column('certificates_generatedcertificate', 'mode')
+
+
+    models = {
+        'auth.group': {
+            'Meta': {'object_name': 'Group'},
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+        },
+        'auth.permission': {
+            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+        },
+        'auth.user': {
+            'Meta': {'object_name': 'User'},
+            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+        },
+        'certificates.certificatewhitelist': {
+            'Meta': {'object_name': 'CertificateWhitelist'},
+            'course_id': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+            'whitelist': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+        },
+        'certificates.generatedcertificate': {
+            'Meta': {'unique_together': "(('user', 'course_id'),)", 'object_name': 'GeneratedCertificate'},
+            'course_id': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '255', 'blank': 'True'}),
+            'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now_add': 'True', 'blank': 'True'}),
+            'distinction': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+            'download_url': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
+            'download_uuid': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '32', 'blank': 'True'}),
+            'error_reason': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '512', 'blank': 'True'}),
+            'grade': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '5', 'blank': 'True'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'key': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '32', 'blank': 'True'}),
+            'mode': ('django.db.models.fields.CharField', [], {'default': "'honor'", 'max_length': '32'}),
+            'modified_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
+            'status': ('django.db.models.fields.CharField', [], {'default': "'unavailable'", 'max_length': '32'}),
+            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+            'verify_uuid': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '32', 'blank': 'True'})
+        },
+        'contenttypes.contenttype': {
+            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+        }
+    }
+
+    complete_apps = ['certificates']
\ No newline at end of file
diff --git a/lms/djangoapps/certificates/models.py b/lms/djangoapps/certificates/models.py
index 8cd1a292c4b87e0e85a921a81056f034d700cb70..eb6ca407a0a93c992aca200d71202d6fad7e84a8 100644
--- a/lms/djangoapps/certificates/models.py
+++ b/lms/djangoapps/certificates/models.py
@@ -1,6 +1,7 @@
 from django.contrib.auth.models import User
 from django.db import models
 from datetime import datetime
+from model_utils import Choices
 
 """
 Certificates are created for a student and an offering of a course.
@@ -62,7 +63,6 @@ class CertificateStatuses(object):
     restricted   = 'restricted'
     unavailable  = 'unavailable'
 
-
 class CertificateWhitelist(models.Model):
     """
     Tracks students who are whitelisted, all users
@@ -86,11 +86,13 @@ class GeneratedCertificate(models.Model):
     key = models.CharField(max_length=32, blank=True, default='')
     distinction = models.BooleanField(default=False)
     status = models.CharField(max_length=32, default='unavailable')
+    MODES = Choices('verified', 'honor', 'audit')
+    mode = models.CharField(max_length=32, choices=MODES, default=MODES.honor)
     name = models.CharField(blank=True, max_length=255)
     created_date = models.DateTimeField(
-            auto_now_add=True, default=datetime.now)
+        auto_now_add=True, default=datetime.now)
     modified_date = models.DateTimeField(
-            auto_now=True, default=datetime.now)
+        auto_now=True, default=datetime.now)
     error_reason = models.CharField(max_length=512, blank=True, default='')
 
     class Meta:
@@ -128,8 +130,9 @@ def certificate_status_for_student(student, course_id):
 
     try:
         generated_certificate = GeneratedCertificate.objects.get(
-                user=student, course_id=course_id)
-        d = {'status': generated_certificate.status}
+            user=student, course_id=course_id)
+        d = {'status': generated_certificate.status,
+             'mode': generated_certificate.mode}
         if generated_certificate.grade:
             d['grade'] = generated_certificate.grade
         if generated_certificate.status == CertificateStatuses.downloadable:
@@ -138,4 +141,4 @@ def certificate_status_for_student(student, course_id):
         return d
     except GeneratedCertificate.DoesNotExist:
         pass
-    return {'status': CertificateStatuses.unavailable}
+    return {'status': CertificateStatuses.unavailable, 'mode': GeneratedCertificate.MODES.honor}
diff --git a/lms/djangoapps/certificates/queue.py b/lms/djangoapps/certificates/queue.py
index 5f63bbf1e2fcf7119fe498d27cf8ff0159fd592d..2f9e70517a167a78630f1273191ac6aa0df578c3 100644
--- a/lms/djangoapps/certificates/queue.py
+++ b/lms/djangoapps/certificates/queue.py
@@ -9,7 +9,8 @@ from capa.xqueue_interface import XQueueInterface
 from capa.xqueue_interface import make_xheader, make_hashkey
 from django.conf import settings
 from requests.auth import HTTPBasicAuth
-from student.models import UserProfile
+from student.models import UserProfile, CourseEnrollment
+from verify_student.models import SoftwareSecurePhotoVerification
 
 import json
 import random
@@ -57,7 +58,7 @@ class XQueueCertInterface(object):
 
         if settings.XQUEUE_INTERFACE.get('basic_auth') is not None:
             requests_auth = HTTPBasicAuth(
-                    *settings.XQUEUE_INTERFACE['basic_auth'])
+                *settings.XQUEUE_INTERFACE['basic_auth'])
         else:
             requests_auth = None
 
@@ -68,10 +69,10 @@ class XQueueCertInterface(object):
             self.request = request
 
         self.xqueue_interface = XQueueInterface(
-                settings.XQUEUE_INTERFACE['url'],
-                settings.XQUEUE_INTERFACE['django_auth'],
-                requests_auth,
-                )
+            settings.XQUEUE_INTERFACE['url'],
+            settings.XQUEUE_INTERFACE['django_auth'],
+            requests_auth,
+        )
         self.whitelist = CertificateWhitelist.objects.all()
         self.restricted = UserProfile.objects.filter(allow_certificate=False)
         self.use_https = True
@@ -84,7 +85,7 @@ class XQueueCertInterface(object):
           course_id - courseenrollment.course_id (string)
 
         WARNING: this command will leave the old certificate, if one exists,
-                 laying around in AWS taking up space. If this is a problem, 
+                 laying around in AWS taking up space. If this is a problem,
                  take pains to clean up storage before running this command.
 
         Change the certificate status to unavailable (if it exists) and request
@@ -92,7 +93,7 @@ class XQueueCertInterface(object):
 
         Return the status object.
         """
-        # TODO: when del_cert is implemented and plumbed through certificates 
+        # TODO: when del_cert is implemented and plumbed through certificates
         #       repo also, do a deletion followed by a creation r/t a simple
         #       recreation. XXX: this leaves orphan cert files laying around in
         #       AWS. See note in the docstring too.
@@ -149,13 +150,15 @@ class XQueueCertInterface(object):
         """
 
         VALID_STATUSES = [status.generating,
-                          status.unavailable, 
-                          status.deleted, 
+                          status.unavailable,
+                          status.deleted,
                           status.error,
                           status.notpassing]
 
         cert_status = certificate_status_for_student(student, course_id)['status']
 
+        new_status = cert_status
+
         if cert_status in VALID_STATUSES:
             # grade the student
 
@@ -165,9 +168,6 @@ class XQueueCertInterface(object):
                 course = courses.get_course_by_id(course_id)
             profile = UserProfile.objects.get(user=student)
 
-            cert, created = GeneratedCertificate.objects.get_or_create(
-                   user=student, course_id=course_id)
-
             # Needed
             self.request.user = student
             self.request.session = {}
@@ -175,45 +175,64 @@ class XQueueCertInterface(object):
             grade = grades.grade(student, self.request, course)
             is_whitelisted = self.whitelist.filter(
                 user=student, course_id=course_id, whitelist=True).exists()
+            enrollment_mode = CourseEnrollment.enrollment_mode_for_user(student, course_id)
+            org = course_id.split('/')[0]
+            course_num = course_id.split('/')[1]
+            cert_mode = enrollment_mode
+            if enrollment_mode == GeneratedCertificate.MODES.verified and SoftwareSecurePhotoVerification.user_is_verified(student):
+                template_pdf = "certificate-template-{0}-{1}-verified.pdf".format(
+                    org, course_num)
+            elif (enrollment_mode == GeneratedCertificate.MODES.verified and not
+                    SoftwareSecurePhotoVerification.user_is_verified(student)):
+                template_pdf = "certificate-template-{0}-{1}.pdf".format(
+                    org, course_num)
+                cert_mode = GeneratedCertificate.MODES.honor
+            else:
+                # honor code and audit students
+                template_pdf = "certificate-template-{0}-{1}.pdf".format(
+                    org, course_num)
 
-            if is_whitelisted or grade['grade'] is not None:
+            cert, created = GeneratedCertificate.objects.get_or_create(
+                user=student, course_id=course_id)
 
-                key = make_hashkey(random.random())
+            cert.mode = cert_mode
+            cert.user = student
+            cert.grade = grade['percent']
+            cert.course_id = course_id
+            cert.name = profile.name
 
-                cert.grade = grade['percent']
-                cert.user = student
-                cert.course_id = course_id
-                cert.key = key
-                cert.name = profile.name
+            if is_whitelisted or grade['grade'] is not None:
 
                 # check to see whether the student is on the
                 # the embargoed country restricted list
                 # otherwise, put a new certificate request
                 # on the queue
+
                 if self.restricted.filter(user=student).exists():
-                    cert.status = status.restricted
+                    new_status = status.restricted
+                    cert.status = new_status
                     cert.save()
                 else:
+                    key = make_hashkey(random.random())
+                    cert.key = key
                     contents = {
                         'action': 'create',
                         'username': student.username,
                         'course_id': course_id,
                         'name': profile.name,
                         'grade': grade['grade'],
+                        'template_pdf': template_pdf,
                     }
-                    cert.status = status.generating
+                    new_status = status.generating
+                    cert.status = new_status
                     cert.save()
                     self._send_to_xqueue(contents, key)
             else:
-                cert_status = status.notpassing
-                cert.grade = grade['percent']
-                cert.user = student
-                cert.course_id = course_id
-                cert.name = profile.name
-                cert.status = cert_status
+                new_status = status.notpassing
+                cert.status = new_status
                 cert.save()
 
-        return cert_status
+        return new_status
 
     def _send_to_xqueue(self, contents, key):
 
@@ -227,7 +246,7 @@ class XQueueCertInterface(object):
                 proto, settings.SITE_NAME, key), key, settings.CERT_QUEUE)
 
         (error, msg) = self.xqueue_interface.send_to_queue(
-                header=xheader, body=json.dumps(contents))
+            header=xheader, body=json.dumps(contents))
         if error:
             logger.critical('Unable to add a request to the queue: {} {}'.format(error, msg))
             raise Exception('Unable to send queue message')
diff --git a/lms/templates/dashboard/_dashboard_certificate_information.html b/lms/templates/dashboard/_dashboard_certificate_information.html
index ea5171c0ef9e9722dc0e1f04f84d04a2dbb92de2..3222b6aae854ca22e0cbadfb0f85b2f7c1e7fbc5 100644
--- a/lms/templates/dashboard/_dashboard_certificate_information.html
+++ b/lms/templates/dashboard/_dashboard_certificate_information.html
@@ -19,7 +19,7 @@ else:
 % elif cert_status['status'] in ('generating', 'ready', 'notpassing', 'restricted'):
       <p class="message-copy">${_("Your final grade:")}
       <span class="grade-value">${"{0:.0f}%".format(float(cert_status['grade'])*100)}</span>.
-      % if cert_status['status'] == 'notpassing':
+      % if cert_status['status'] == 'notpassing' and enrollment.mode != 'audit':
          ${_("Grade required for a certificate:")} <span class="grade-value">
            ${"{0:.0f}%".format(float(course.lowest_passing_grade)*100)}</span>.
       % elif cert_status['status'] == 'restricted' and enrollment.mode == 'verified':
@@ -44,6 +44,12 @@ else:
       <a class="btn" href="${cert_status['download_url']}"
          title="${_('This link will open/download a PDF document')}">
          ${_("Download Your Certificate (PDF)")}</a></li>
+    % elif cert_status['show_download_url'] and enrollment.mode == 'verified' and cert_status['mode'] == 'honor':
+      <li class="action">
+      <p>${_('Since we did not have a valid set of verification photos from you when certificates were generated, we could not grant you a verified certificate. An honor code certificate has been granted instead.')}</p>
+      <a class="btn" href="${cert_status['download_url']}"
+         title="${_('This link will open/download a PDF document')}">
+         ${_("Download Your Certificate (PDF)")}</a></li>
     % elif cert_status['show_download_url'] and enrollment.mode == 'verified':
       <li class="action">
       <a class="btn" href="${cert_status['download_url']}"