diff --git a/lms/djangoapps/certificates/generation.py b/lms/djangoapps/certificates/generation.py
index 9a0b944f8a41544ad303fc21fd9fc0be8ac8eca1..a6485c57ab9e852a3d7c65ba4e1ed2e4a76a6742 100644
--- a/lms/djangoapps/certificates/generation.py
+++ b/lms/djangoapps/certificates/generation.py
@@ -10,10 +10,9 @@ These methods should be called from tasks.
 import logging
 from uuid import uuid4
 
-from common.djangoapps.student import models_api as student_api
 from lms.djangoapps.certificates.data import CertificateStatuses
 from lms.djangoapps.certificates.models import GeneratedCertificate
-from lms.djangoapps.certificates.utils import emit_certificate_event
+from lms.djangoapps.certificates.utils import emit_certificate_event, get_preferred_certificate_name
 
 log = logging.getLogger(__name__)
 
@@ -66,9 +65,7 @@ def _generate_certificate(user, course_key, status, enrollment_mode, course_grad
     # Retrieve the existing certificate for the learner if it exists
     existing_certificate = GeneratedCertificate.certificate_for_student(user, course_key)
 
-    profile_name = student_api.get_name(user.id)
-    if not profile_name:
-        profile_name = ''
+    preferred_name = get_preferred_certificate_name(user)
 
     # Retain the `verify_uuid` from an existing certificate if possible, this will make it possible for the learner to
     # keep the existing URL to their certificate
@@ -84,7 +81,7 @@ def _generate_certificate(user, course_key, status, enrollment_mode, course_grad
             'user': user,
             'course_id': course_key,
             'mode': enrollment_mode,
-            'name': profile_name,
+            'name': preferred_name,
             'status': status,
             'grade': course_grade,
             'download_url': '',
diff --git a/lms/djangoapps/certificates/models.py b/lms/djangoapps/certificates/models.py
index 005f4c66e395d66b6669f8eb1324955b831fb440..e76849f35a3656e36f247c0ec9091497be1c14d1 100644
--- a/lms/djangoapps/certificates/models.py
+++ b/lms/djangoapps/certificates/models.py
@@ -18,6 +18,8 @@ from django.db.models import Count
 from django.dispatch import receiver
 
 from django.utils.translation import ugettext_lazy as _
+from edx_name_affirmation.api import get_verified_name, should_use_verified_name_for_certs
+from edx_name_affirmation.toggles import is_verified_name_enabled
 from model_utils import Choices
 from model_utils.models import TimeStampedModel
 from opaque_keys.edx.django.models import CourseKeyField
@@ -370,9 +372,7 @@ class GeneratedCertificate(models.Model):
         if not mode:
             mode = self.mode
 
-        profile_name = student_api.get_name(self.user.id)
-        if not profile_name:
-            profile_name = ''
+        preferred_name = self._get_preferred_certificate_name(self.user)
 
         self.error_reason = ''
         self.download_uuid = ''
@@ -380,7 +380,7 @@ class GeneratedCertificate(models.Model):
         self.grade = grade
         self.status = status
         self.mode = mode
-        self.name = profile_name
+        self.name = preferred_name
         self.save()
 
         COURSE_CERT_REVOKED.send_robust(
@@ -404,6 +404,23 @@ class GeneratedCertificate(models.Model):
             }
             emit_certificate_event('revoked', self.user, str(self.course_id), event_data=event_data)
 
+    def _get_preferred_certificate_name(self, user):
+        """
+        Copy of `get_preferred_certificate_name` from utils.py - importing it here would introduce
+        a circular dependency.
+        """
+        name_to_use = student_api.get_name(user.id)
+
+        if is_verified_name_enabled() and should_use_verified_name_for_certs(user):
+            verified_name_obj = get_verified_name(user, is_verified=True)
+            if verified_name_obj:
+                name_to_use = verified_name_obj.verified_name
+
+        if not name_to_use:
+            name_to_use = ''
+
+        return name_to_use
+
     def is_valid(self):
         """
         Return True if certificate is valid else return False.
diff --git a/lms/djangoapps/certificates/tests/test_generation.py b/lms/djangoapps/certificates/tests/test_generation.py
index e7e752fd502e58108620b96bac2f55c5d126804c..add17cdae77eddf4fa655d56ac3ceafdb39a9f5e 100644
--- a/lms/djangoapps/certificates/tests/test_generation.py
+++ b/lms/djangoapps/certificates/tests/test_generation.py
@@ -1,9 +1,14 @@
 """
 Tests for certificate generation
 """
+import ddt
 import logging
 from unittest import mock
 
+from edx_name_affirmation.api import create_verified_name, create_verified_name_config
+from edx_name_affirmation.toggles import VERIFIED_NAME_FLAG
+from edx_toggles.toggles.testutils import override_waffle_flag
+
 from common.djangoapps.course_modes.models import CourseMode
 from common.djangoapps.student.models import UserProfile
 from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
@@ -20,6 +25,7 @@ log = logging.getLogger(__name__)
 PROFILE_NAME_METHOD = 'common.djangoapps.student.models_api.get_name'
 
 
+@ddt.ddt
 class CertificateTests(EventTestMixin, ModuleStoreTestCase):
     """
     Tests for certificate generation
@@ -187,3 +193,34 @@ class CertificateTests(EventTestMixin, ModuleStoreTestCase):
             assert cert.mode == self.enrollment_mode
             assert cert.grade == self.grade
             assert cert.name == ''
+
+    @override_waffle_flag(VERIFIED_NAME_FLAG, active=True)
+    @ddt.data((True, True), (True, False), (False, False))
+    @ddt.unpack
+    def test_generation_verified_name(self, should_use_verified_name_for_certs, is_verified):
+        """
+        Test that if verified name functionality is enabled and the user has their preference set to use
+        verified name for certificates, their verified name will appear on the certificate rather than
+        their profile name.
+        """
+        verified_name = 'Jonathan Doe'
+        create_verified_name(self.u, verified_name, self.name, is_verified=is_verified)
+        create_verified_name_config(self.u, use_verified_name_for_certs=should_use_verified_name_for_certs)
+
+        GeneratedCertificateFactory(
+            user=self.u,
+            course_id=self.key,
+            mode=CourseMode.AUDIT,
+            status=CertificateStatuses.unverified
+        )
+
+        generate_course_certificate(
+            self.u, self.key, CertificateStatuses.downloadable, self.enrollment_mode, self.grade, self.gen_mode,
+        )
+
+        cert = GeneratedCertificate.objects.get(user=self.u, course_id=self.key)
+
+        if should_use_verified_name_for_certs and is_verified:
+            assert cert.name == verified_name
+        else:
+            assert cert.name == self.name
diff --git a/lms/djangoapps/certificates/tests/test_models.py b/lms/djangoapps/certificates/tests/test_models.py
index 456c471cb535d51004f2566c66275b80871cdef7..2025c27289d0d909ed6969b66932f5bb1feee8e4 100644
--- a/lms/djangoapps/certificates/tests/test_models.py
+++ b/lms/djangoapps/certificates/tests/test_models.py
@@ -12,6 +12,9 @@ from django.core.exceptions import ValidationError
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.test import TestCase
 from django.test.utils import override_settings
+from edx_name_affirmation.api import create_verified_name, create_verified_name_config
+from edx_name_affirmation.toggles import VERIFIED_NAME_FLAG
+from edx_toggles.toggles.testutils import override_waffle_flag
 from opaque_keys.edx.locator import CourseKey, CourseLocator
 from path import Path as path
 
@@ -360,6 +363,7 @@ class CertificateInvalidationTest(SharedModuleStoreTestCase):
         assert mock_revoke_task.call_args[0] == (self.user.username, str(self.course_id))
 
 
+@ddt.ddt
 class GeneratedCertificateTest(SharedModuleStoreTestCase):
     """
     Test GeneratedCertificates
@@ -540,6 +544,35 @@ class GeneratedCertificateTest(SharedModuleStoreTestCase):
 
         self._assert_event_data(mock_emit_certificate_event, expected_event_data)
 
+    @override_waffle_flag(VERIFIED_NAME_FLAG, active=True)
+    @ddt.data((True, True), (True, False), (False, False))
+    @ddt.unpack
+    def test_invalidate_with_verified_name(self, should_use_verified_name_for_certs, is_verified):
+        """
+        Test the invalidate method with verified name turned on for the user's certificates
+        """
+        verified_name = 'Jonathan Doe'
+        profile = UserProfile.objects.get(user=self.user)
+        create_verified_name(self.user, verified_name, profile.name, is_verified=is_verified)
+        create_verified_name_config(self.user, use_verified_name_for_certs=should_use_verified_name_for_certs)
+
+        cert = GeneratedCertificateFactory.create(
+            status=CertificateStatuses.downloadable,
+            user=self.user,
+            course_id=self.course_key,
+            mode=CourseMode.AUDIT,
+            name='Fuzzy Hippo'
+        )
+        mode = CourseMode.VERIFIED
+        source = 'invalidated_test'
+        cert.invalidate(mode=mode, source=source)
+
+        cert = GeneratedCertificate.objects.get(user=self.user, course_id=self.course_key)
+        if should_use_verified_name_for_certs and is_verified:
+            assert cert.name == verified_name
+        else:
+            assert cert.name == profile.name
+
     @patch('lms.djangoapps.certificates.utils.emit_certificate_event')
     def test_unverified(self, mock_emit_certificate_event):
         """
diff --git a/lms/djangoapps/certificates/tests/test_webview_views.py b/lms/djangoapps/certificates/tests/test_webview_views.py
index a389e297a99f44166b0ec7e51cf5e544467d8b25..188e4b737be20e394d483eca691553de96d6c107 100644
--- a/lms/djangoapps/certificates/tests/test_webview_views.py
+++ b/lms/djangoapps/certificates/tests/test_webview_views.py
@@ -12,8 +12,10 @@ from django.conf import settings
 from django.test.client import Client, RequestFactory
 from django.test.utils import override_settings
 from django.urls import reverse
+from edx_name_affirmation.api import create_verified_name, create_verified_name_config
+from edx_name_affirmation.toggles import VERIFIED_NAME_FLAG
 from edx_toggles.toggles import LegacyWaffleSwitch
-from edx_toggles.toggles.testutils import override_waffle_switch
+from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch
 from organizations import api as organizations_api
 
 from common.djangoapps.course_modes.models import CourseMode
@@ -1524,6 +1526,35 @@ class CertificatesViewsTests(CommonCertificatesTestCase, CacheIsolationTestCase)
                 )
             )
 
+    @override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED)
+    @override_waffle_flag(VERIFIED_NAME_FLAG, active=True)
+    @ddt.data((True, True), (True, False), (False, False))
+    @ddt.unpack
+    def test_certificate_view_verified_name(self, should_use_verified_name_for_certs, is_verified):
+        """
+        Test that if verified name functionality is enabled and the user has their preference set to use
+        verified name for certificates, their verified name will appear on the certificate rather than
+        their profile name.
+        """
+        verified_name = 'Jonathan Doe'
+        create_verified_name(self.user, verified_name, self.user.profile.name, is_verified=is_verified)
+        create_verified_name_config(self.user, use_verified_name_for_certs=should_use_verified_name_for_certs)
+
+        self._add_course_certificates(count=1, signatory_count=1)
+        test_url = get_certificate_url(
+            user_id=self.user.id,
+            course_id=str(self.course.id),
+            uuid=self.cert.verify_uuid
+        )
+
+        response = self.client.get(test_url, HTTP_HOST='test.localhost')
+        if should_use_verified_name_for_certs and is_verified:
+            self.assertContains(response, verified_name)
+            self.assertNotContains(response, self.user.profile.name)
+        else:
+            self.assertContains(response, self.user.profile.name)
+            self.assertNotContains(response, verified_name)
+
 
 class CertificateEventTests(CommonCertificatesTestCase, EventTrackingTestCase):
     """
diff --git a/lms/djangoapps/certificates/utils.py b/lms/djangoapps/certificates/utils.py
index da3fd0db450fc41fbf4ace8c9830f216b3f318b2..d4111436589ca31a43e5ce84e0cdbba9d213c462 100644
--- a/lms/djangoapps/certificates/utils.py
+++ b/lms/djangoapps/certificates/utils.py
@@ -4,12 +4,16 @@ Certificates utilities
 from datetime import datetime
 import logging
 
+from edx_name_affirmation.api import get_verified_name, should_use_verified_name_for_certs
+from edx_name_affirmation.toggles import is_verified_name_enabled
+
 from django.conf import settings
 from django.urls import reverse
 from eventtracking import tracker
 from opaque_keys.edx.keys import CourseKey
 from pytz import utc
 
+from common.djangoapps.student import models_api as student_api
 from lms.djangoapps.certificates.data import CertificateStatuses
 from lms.djangoapps.certificates.models import GeneratedCertificate
 from openedx.core.djangoapps.content.course_overviews.api import get_course_overview_or_none
@@ -228,3 +232,22 @@ def certificate_status_for_student(student, course_id):
     except GeneratedCertificate.DoesNotExist:
         generated_certificate = None
     return certificate_status(generated_certificate)
+
+
+def get_preferred_certificate_name(user):
+    """
+    If the verified name feature is enabled and the user has their preference set to use their
+    verified name for certificates, return their verified name. Else, return the user's profile
+    name, or an empty string if it doesn't exist.
+    """
+    name_to_use = student_api.get_name(user.id)
+
+    if is_verified_name_enabled() and should_use_verified_name_for_certs(user):
+        verified_name_obj = get_verified_name(user, is_verified=True)
+        if verified_name_obj:
+            name_to_use = verified_name_obj.verified_name
+
+    if not name_to_use:
+        name_to_use = ''
+
+    return name_to_use
diff --git a/lms/djangoapps/certificates/views/webview.py b/lms/djangoapps/certificates/views/webview.py
index f37b3c64e45eb0fa1d6f2d8d40149bf973a8e246..e18137eacde31d7d6e204c052fc99ee0efdfb9ab 100644
--- a/lms/djangoapps/certificates/views/webview.py
+++ b/lms/djangoapps/certificates/views/webview.py
@@ -43,7 +43,11 @@ from lms.djangoapps.certificates.models import (
     GeneratedCertificate
 )
 from lms.djangoapps.certificates.permissions import PREVIEW_CERTIFICATES
-from lms.djangoapps.certificates.utils import emit_certificate_event, get_certificate_url
+from lms.djangoapps.certificates.utils import (
+    emit_certificate_event,
+    get_certificate_url,
+    get_preferred_certificate_name
+)
 from openedx.core.djangoapps.catalog.api import get_course_run_details
 from openedx.core.djangoapps.certificates.api import display_date_for_certificate
 from openedx.core.djangoapps.content.course_overviews.api import get_course_overview_or_none
@@ -305,7 +309,8 @@ def _update_context_with_user_info(context, user, user_certificate):
     """
     Updates context dictionary with user related info.
     """
-    user_fullname = user.profile.name
+    user_fullname = get_preferred_certificate_name(user)
+
     context['username'] = user.username
     context['course_mode'] = user_certificate.mode
     context['accomplishment_user_id'] = user.id