diff --git a/lti_consumer/data.py b/lti_consumer/data.py
index b450115db5d3becfaed4a1cb8bc41357ed5e8c43..5b10a3f02dbda9525154c48d2a69c1caf7806f3f 100644
--- a/lti_consumer/data.py
+++ b/lti_consumer/data.py
@@ -45,6 +45,8 @@ class Lti1p3LaunchData:
     * config_id (required): The config_id field of an LtiConfiguration to use for the launch.
     * resource_link_id (required): A unique identifier that is guaranteed to be unique for each placement of the LTI
         link.
+    * preferred_username (optional): The user's username.
+    * email (optional): The user's email.
     * external_user_id (optional): A unique identifier for the user that is requesting the LTI 1.3 launch that can be
         shared externally. The identifier must be stable to the issuer. This value will be sent to the the Tool in the
         form of both the login_hint in the login initiation request and the sub claim in the ID token of the LTI 1.3
@@ -73,6 +75,8 @@ class Lti1p3LaunchData:
     user_role = field()
     config_id = field()
     resource_link_id = field()
+    preferred_username = field(default=None)
+    email = field(default=None)
     external_user_id = field(default=None)
     launch_presentation_document_target = field(default=None)
     launch_presentation_return_url = field(default=None)
diff --git a/lti_consumer/lti_1p3/consumer.py b/lti_consumer/lti_1p3/consumer.py
index 6360227de84f07c2f2340fcf784ef9cb9a606ef5..00a31bf1f81252740f728774ee6d643db89c301f 100644
--- a/lti_consumer/lti_1p3/consumer.py
+++ b/lti_consumer/lti_1p3/consumer.py
@@ -132,7 +132,8 @@ class LtiConsumer1p3:
             user_id,
             role,
             full_name=None,
-            email_address=None
+            email_address=None,
+            preferred_username=None,
     ):
         """
         Set user data/roles and convert to IMS Specification
@@ -162,6 +163,11 @@ class LtiConsumer1p3:
                 "email": email_address,
             })
 
+        if preferred_username:
+            self.lti_claim_user_data.update({
+                "preferred_username": preferred_username,
+            })
+
     def set_resource_link_claim(
         self,
         resource_link_id,
diff --git a/lti_consumer/lti_1p3/tests/test_consumer.py b/lti_consumer/lti_1p3/tests/test_consumer.py
index 9528e344c2a927cf43d5924b98b205de25c526aa..7ba2e6865e0baa27d7cc32a7af6676516e71034e 100644
--- a/lti_consumer/lti_1p3/tests/test_consumer.py
+++ b/lti_consumer/lti_1p3/tests/test_consumer.py
@@ -210,12 +210,20 @@ class TestLti1p3Consumer(TestCase):
         ),
         # User with extra data
         (
-            {"user_id": "1", "role": '', "full_name": "Jonh", "email_address": "jonh@example.com"},
+            {
+                "user_id": "1",
+                "role": '',
+                "full_name":
+                "Jonh",
+                "email_address":
+                "jonh@example.com",
+                "preferred_username": "johnuser"},
             {
                 "sub": "1",
                 "https://purl.imsglobal.org/spec/lti/claim/roles": [],
                 "name": "Jonh",
-                "email": "jonh@example.com"
+                "email": "jonh@example.com",
+                "preferred_username": "johnuser",
             }
         ),
     )
diff --git a/lti_consumer/lti_xblock.py b/lti_consumer/lti_xblock.py
index fcb53d30b3dd16f7edf7fbe3f37eefc54d760aad..f5b912c13a50b2a013db701c081b92c3d2e130a1 100644
--- a/lti_consumer/lti_xblock.py
+++ b/lti_consumer/lti_xblock.py
@@ -673,6 +673,26 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
             log.exception('Something went wrong in reading the LTI XBlock configuration.')
             raise
 
+    def get_pii_sharing_enabled(self):
+        """
+        Returns whether PII can be transmitted via this XBlock. This controls both whether the PII sharing XBlock
+        fields ask_to_send_username and ask_to_send_email are displayed in Studio and whether these data are shared
+        in LTI launches, regardless of the values of the settings on the XBlock.
+        """
+        config_service = self.runtime.service(self, 'lti-configuration')
+        if config_service:
+            is_already_sharing_learner_info = self.ask_to_send_email or self.ask_to_send_username
+
+            return config_service.configuration.lti_access_to_learners_editable(
+                self.scope_ids.usage_id.context_key,
+                is_already_sharing_learner_info,
+            )
+
+        # TODO: The LTI configuration service is currently only available from the studio_view. This means that
+        #       the CourseAllowPIISharingInLTIFlag does not control PII sharing in the author_view or student_view,
+        #       because the service is not defined in those contexts.
+        return True
+
     @property
     def editable_fields(self):
         """
@@ -710,14 +730,9 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
 
         # update the editable fields if this XBlock is configured to not to allow the
         # editing of 'ask_to_send_username' and 'ask_to_send_email'.
-        config_service = self.runtime.service(self, 'lti-configuration')
-        if config_service:
-            is_already_sharing_learner_info = self.ask_to_send_email or self.ask_to_send_username
-            if not config_service.configuration.lti_access_to_learners_editable(
-                    self.scope_ids.usage_id.context_key,
-                    is_already_sharing_learner_info,
-            ):
-                noneditable_fields.extend(['ask_to_send_username', 'ask_to_send_email'])
+        pii_sharing_enabled = self.get_pii_sharing_enabled()
+        if not pii_sharing_enabled:
+            noneditable_fields.extend(['ask_to_send_username', 'ask_to_send_email'])
 
         editable_fields = tuple(
             field
@@ -1164,10 +1179,13 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
 
         username = None
         email = None
-        if self.ask_to_send_username and real_user_data['user_username']:
-            username = real_user_data['user_username']
-        if self.ask_to_send_email and real_user_data['user_email']:
-            email = real_user_data['user_email']
+        # Send PII fields only if this XBlock is configured to allow the sending PII.
+        pii_sharing_enabled = self.get_pii_sharing_enabled()
+        if pii_sharing_enabled:
+            if self.ask_to_send_username and real_user_data['user_username']:
+                username = real_user_data['user_username']
+            if self.ask_to_send_email and real_user_data['user_email']:
+                email = real_user_data['user_email']
 
         lti_consumer.set_user_data(
             user_id,
@@ -1478,12 +1496,26 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
         location = self.scope_ids.usage_id
         course_key = str(location.context_key)
 
+        username = None
+        email = None
+
+        pii_sharing_enabled = self.get_pii_sharing_enabled()
+        if pii_sharing_enabled:
+            user_data = self.extract_real_user_data()
+
+            if self.ask_to_send_username and user_data['user_username']:
+                username = user_data['user_username']
+            if self.ask_to_send_email and user_data['user_email']:
+                email = user_data['user_email']
+
         launch_data = Lti1p3LaunchData(
             user_id=self.lms_user_id,
             user_role=self.role,
             config_id=config_id,
             resource_link_id=str(location),
             external_user_id=self.external_user_id,
+            preferred_username=username,
+            email=email,
             launch_presentation_document_target="iframe",
             context_id=course_key,
             context_type=["course_offering"],
@@ -1568,6 +1600,9 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
         lti_block_launch_handler = self._get_lti_block_launch_handler()
         lti_1p3_launch_url = self._get_lti_1p3_launch_url(lti_consumer)
 
+        # The values of ask_to_send_username and ask_to_send_email should only apply if PII sharing is enabled.
+        pii_sharing_enabled = self.get_pii_sharing_enabled()
+
         return {
             'launch_url': launch_url.strip(),
             'lti_1p3_launch_url': lti_1p3_launch_url,
@@ -1582,8 +1617,8 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
             'module_score': self.module_score,
             'comment': sanitized_comment,
             'description': self.description,
-            'ask_to_send_username': self.ask_to_send_username,
-            'ask_to_send_email': self.ask_to_send_email,
+            'ask_to_send_username': self.ask_to_send_username if pii_sharing_enabled else False,
+            'ask_to_send_email': self.ask_to_send_email if pii_sharing_enabled else False,
             'button_text': self.button_text,
             'inline_height': self.inline_height,
             'modal_vertical_offset': self._get_modal_position_offset(self.modal_height),
diff --git a/lti_consumer/plugin/views.py b/lti_consumer/plugin/views.py
index 4e7428dadfaa9de72220253d2b41b86e5f408b6d..c6503b280fbdff6edd941821d3201e6ccf570e2c 100644
--- a/lti_consumer/plugin/views.py
+++ b/lti_consumer/plugin/views.py
@@ -187,6 +187,8 @@ def launch_gate_endpoint(request, suffix=None):  # pylint: disable=unused-argume
         lti_consumer.set_user_data(
             user_id=user_id,
             role=user_role,
+            email_address=launch_data.email,
+            preferred_username=launch_data.preferred_username,
         )
 
         # Set resource_link claim.
diff --git a/lti_consumer/tests/test_utils.py b/lti_consumer/tests/test_utils.py
index f31c0781799941ff87e14cf200c829239de9aa6b..727e012341ffa148bd3a352e9889e631337632e8 100644
--- a/lti_consumer/tests/test_utils.py
+++ b/lti_consumer/tests/test_utils.py
@@ -92,3 +92,19 @@ defaulting_processor.lti_xblock_default_params = {
     'custom_name': 'Lex',
     'custom_country': '',
 }
+
+
+def get_mock_lti_configuration(editable):
+    """
+    Returns a mock object of lti-configuration service
+
+    Arguments:
+        editable (bool): This indicates whether the LTI fields (i.e. 'ask_to_send_username' and
+        'ask_to_send_email') are editable.
+    """
+    lti_configuration = Mock()
+    lti_configuration.configuration = Mock()
+    lti_configuration.configuration.lti_access_to_learners_editable = Mock(
+        return_value=editable
+    )
+    return lti_configuration
diff --git a/lti_consumer/tests/unit/test_lti_xblock.py b/lti_consumer/tests/unit/test_lti_xblock.py
index 2f8987d2b82765f7008cc316d8fa079ee7eb040f..eb4a8c7198f2dbe050823754de80312d8825ab14 100644
--- a/lti_consumer/tests/unit/test_lti_xblock.py
+++ b/lti_consumer/tests/unit/test_lti_xblock.py
@@ -23,7 +23,13 @@ from lti_consumer.data import Lti1p3LaunchData
 from lti_consumer.lti_xblock import LtiConsumerXBlock, parse_handler_suffix, valid_config_type_values
 from lti_consumer.lti_1p3.tests.utils import create_jwt
 from lti_consumer.tests import test_utils
-from lti_consumer.tests.test_utils import FAKE_USER_ID, make_jwt_request, make_request, make_xblock
+from lti_consumer.tests.test_utils import (
+    FAKE_USER_ID,
+    get_mock_lti_configuration,
+    make_jwt_request,
+    make_request,
+    make_xblock,
+)
 from lti_consumer.utils import resolve_custom_parameter_template
 
 HTML_PROBLEM_PROGRESS = '<div class="problem-progress">'
@@ -460,21 +466,6 @@ class TestEditableFields(TestLtiConsumerXBlock):
         self.mock_database_config_enabled_patcher.stop()
         super().tearDown()
 
-    def get_mock_lti_configuration(self, editable):
-        """
-        Returns a mock object of lti-configuration service
-
-        Arguments:
-            editable (bool): This indicates whether the LTI fields (i.e. 'ask_to_send_username' and
-            'ask_to_send_email') are editable.
-        """
-        lti_configuration = Mock()
-        lti_configuration.configuration = Mock()
-        lti_configuration.configuration.lti_access_to_learners_editable = Mock(
-            return_value=editable
-        )
-        return lti_configuration
-
     def are_fields_editable(self, fields):
         """
         Returns whether the fields passed in as an argument, are editable.
@@ -499,7 +490,7 @@ class TestEditableFields(TestLtiConsumerXBlock):
         are editable when this XBlock is configured to allow it.
         """
         # this XBlock is configured to allow editing of LTI fields
-        self.xblock.runtime.service.return_value = self.get_mock_lti_configuration(editable=True)
+        self.xblock.runtime.service.return_value = get_mock_lti_configuration(editable=True)
         # Assert that 'ask_to_send_username' and 'ask_to_send_email' are editable.
         self.assertTrue(self.are_fields_editable(fields=['ask_to_send_username', 'ask_to_send_email']))
 
@@ -509,7 +500,7 @@ class TestEditableFields(TestLtiConsumerXBlock):
         are not editable when this XBlock is configured to not to allow it.
         """
         # this XBlock is configured to not to allow editing of LTI fields
-        self.xblock.runtime.service.return_value = self.get_mock_lti_configuration(editable=False)
+        self.xblock.runtime.service.return_value = get_mock_lti_configuration(editable=False)
         # Assert that 'ask_to_send_username' and 'ask_to_send_email' are not editable.
         self.assertFalse(self.are_fields_editable(fields=['ask_to_send_username', 'ask_to_send_email']))
 
@@ -818,11 +809,11 @@ class TestStudentView(TestLtiConsumerXBlock):
         )
 
 
+@ddt.ddt
 class TestLtiLaunchHandler(TestLtiConsumerXBlock):
     """
     Unit tests for LtiConsumerXBlock.lti_launch_handler()
     """
-
     def setUp(self):
         super().setUp()
         self.mock_lti_consumer = Mock(
@@ -923,6 +914,34 @@ class TestLtiLaunchHandler(TestLtiConsumerXBlock):
             }
         )
 
+    @patch('lti_consumer.lti_xblock.LtiConsumerXBlock.anonymous_user_id', PropertyMock(return_value=FAKE_USER_ID))
+    @ddt.idata(product([True, False], [True, False], [True, False]))
+    @ddt.unpack
+    def test_lti_launch_pii_sharing(self, pii_sharing_enabled, ask_to_send_username, ask_to_send_email):
+        """
+        Test that the values of the LTI 1.1 PII fields person_sourcedid and person_contact_email_primary that are set
+        on the LTI consumer are actual values for those fields only when PII sharing is enabled. If PII sharing is not
+        enabled, then the values should be None.
+        """
+        self.xblock.get_pii_sharing_enabled = Mock(return_value=pii_sharing_enabled)
+
+        self.xblock.ask_to_send_username = ask_to_send_username
+        self.xblock.ask_to_send_email = ask_to_send_email
+
+        request = make_request('', 'GET')
+        self.xblock.lti_launch_handler(request)
+
+        set_user_data_kwargs = {
+            'result_sourcedid': self.xblock.lis_result_sourcedid,
+        }
+
+        set_user_data_kwargs['person_sourcedid'] = 'fake' if pii_sharing_enabled and ask_to_send_username else None
+        set_user_data_kwargs['person_contact_email_primary'] = (
+            'abc@example.com' if pii_sharing_enabled and ask_to_send_email else None
+        )
+
+        self.mock_lti_consumer.set_user_data.assert_called_with(FAKE_USER_ID, 'Student,Learner', **set_user_data_kwargs)
+
 
 class TestOutcomeServiceHandler(TestLtiConsumerXBlock):
     """
@@ -1467,6 +1486,26 @@ class TestGetContext(TestLtiConsumerXBlock):
         context = self.xblock._get_context_for_template()  # pylint: disable=protected-access
         self.assertEqual(context['lti_1p3_launch_url'], lti_1p3_launch_url)
 
+    @ddt.idata(product([True, False], [True, False], [True, False]))
+    @ddt.unpack
+    def test_context_pii_sharing(self, pii_sharing_enabled, ask_to_send_username, ask_to_send_email):
+        """
+        Test that the values for context keys ask_to_send_username and ask_to_send_email are the values of the
+        corresponding XBlock fields only when PII sharing is enabled. Otherwise, they should always be False.
+        """
+        self.xblock.get_pii_sharing_enabled = Mock(return_value=pii_sharing_enabled)
+        self.xblock.ask_to_send_username = ask_to_send_username
+        self.xblock.ask_to_send_email = ask_to_send_email
+
+        context = self.xblock._get_context_for_template()  # pylint: disable=protected-access
+
+        if pii_sharing_enabled:
+            self.assertEqual(context['ask_to_send_username'], self.xblock.ask_to_send_username)
+            self.assertEqual(context['ask_to_send_email'], self.xblock.ask_to_send_email)
+        else:
+            self.assertEqual(context['ask_to_send_username'], False)
+            self.assertEqual(context['ask_to_send_email'], False)
+
 
 @ddt.ddt
 class TestProcessorSettings(TestLtiConsumerXBlock):
@@ -1533,6 +1572,7 @@ class TestGetModalPositionOffset(TestLtiConsumerXBlock):
         self.assertEqual(offset, 10)
 
 
+@ddt.ddt
 class TestLtiConsumer1p3XBlock(TestCase):
     """
     Unit tests for LtiConsumerXBlock when using an LTI 1.3 tool.
@@ -1554,16 +1594,22 @@ class TestLtiConsumer1p3XBlock(TestCase):
         self.addCleanup(self.mock_filter_enabled_patcher.stop)
         self.addCleanup(self.mock_database_config_enabled_patcher.stop)
 
-    def test_get_lti_1p3_launch_data(self):
+    @ddt.idata(product([True, False], [True, False], [True, False]))
+    @ddt.unpack
+    def test_get_lti_1p3_launch_data(self, pii_sharing_enabled, send_username, send_email):
         """
         Test that get_lti_1p3_launch_data returns an instance of Lti1p3LaunchData with the correct data.
         """
         # Mock out the user role and external_user_id properties.
         fake_user = Mock()
+        fake_user_email = 'fake_email@example.com'
+        fake_username = 'fake_username'
+        fake_user.emails = [fake_user_email]
         fake_user.opt_attrs = {
             'edx-platform.user_id': 1,
             'edx-platform.user_role': 'instructor',
             'edx-platform.is_authenticated': True,
+            'edx-platform.username': fake_username,
         }
         self.xblock.runtime.service(self, 'user').get_current_user = Mock(return_value=fake_user)
         self.xblock.runtime.service(self, 'user').get_external_user_id = Mock(return_value="external_user_id")
@@ -1571,9 +1617,34 @@ class TestLtiConsumer1p3XBlock(TestCase):
         # Mock out get_context_title to avoid calling into the compatability layer.
         self.xblock.get_context_title = Mock(return_value="context_title")
 
+        # Mock out get_pii_sharing_enabled to reduce the amount of mocking we have to do.
+        self.xblock.get_pii_sharing_enabled = Mock(return_value=pii_sharing_enabled)
+
         launch_data = self.xblock.get_lti_1p3_launch_data()
 
         course_key = str(self.xblock.scope_ids.usage_id.course_key)
+
+        expected_launch_data_kwargs = {
+            "user_id": 1,
+            "user_role": "instructor",
+            "config_id": config_id_for_block(self.xblock),
+            "resource_link_id": str(self.xblock.scope_ids.usage_id),
+            "external_user_id": "external_user_id",
+            "launch_presentation_document_target": "iframe",
+            "message_type": "LtiResourceLinkRequest",
+            "context_id": course_key,
+            "context_type": ["course_offering"],
+            "context_title": "context_title",
+            "context_label": course_key,
+        }
+
+        if pii_sharing_enabled:
+            if send_username:
+                expected_launch_data_kwargs["preferred_username"] = fake_username
+
+            if send_email:
+                expected_launch_data_kwargs["email"] = fake_user_email
+
         expected_launch_data = Lti1p3LaunchData(
             user_id=1,
             user_role="instructor",
@@ -1928,3 +1999,46 @@ class TestSubmitStudioEditsHandler(TestLtiConsumerXBlock):
         )
         external_config_flag_patcher.start()
         self.addCleanup(external_config_flag_patcher.stop)
+
+
+@ddt.ddt
+class TestGetPiiSharingEnabled(TestLtiConsumerXBlock):
+    """
+    Unit tests for LtiConsumerXBlock.get_pii_sharing_enabled.
+    """
+    def test_no_service(self):
+        self.assertTrue(self.xblock.get_pii_sharing_enabled())
+
+    @ddt.data(True, False)
+    def test_lti_access_to_learners_editable(self, lti_access_to_learners_editable):
+        """
+        Test that the get_pii_sharing_enabled method returns the value of calling the lti_access_to_learners_editable
+        method of the LTI configuration service, so long as as the configuration service is available and defined.
+        """
+        self.xblock.runtime.service.return_value = get_mock_lti_configuration(
+            editable=lti_access_to_learners_editable
+        )
+        self.assertEqual(self.xblock.get_pii_sharing_enabled(), lti_access_to_learners_editable)
+
+    @ddt.idata(product([True, False], [True, False]))
+    @ddt.unpack
+    def test_lti_access_to_learners_editable_args(self, ask_to_send_username, ask_to_send_email):
+        """
+        Test that the lti_access_to_learners_editable_mock method of the LTI configuration service is called with the
+        the correct arguments.
+        """
+        lti_configuration = Mock()
+        lti_configuration.configuration = Mock()
+        lti_access_to_learners_editable_mock = Mock()
+        lti_configuration.configuration.lti_access_to_learners_editable = lti_access_to_learners_editable_mock
+        self.xblock.runtime.service.return_value = lti_configuration
+
+        self.xblock.ask_to_send_username = ask_to_send_username
+        self.xblock.ask_to_send_email = ask_to_send_email
+
+        self.xblock.get_pii_sharing_enabled()
+
+        lti_access_to_learners_editable_mock.assert_called_once_with(
+            self.xblock.scope_ids.usage_id.context_key,
+            ask_to_send_username or ask_to_send_email,
+        )