diff --git a/lms/djangoapps/experiments/tests/test_utils.py b/lms/djangoapps/experiments/tests/test_utils.py
index 83ee0d39e63125c225405490b9ca776bb9f57849..62eb8573a5704aca6dd85ffeaa312efdb717f46c 100644
--- a/lms/djangoapps/experiments/tests/test_utils.py
+++ b/lms/djangoapps/experiments/tests/test_utils.py
@@ -1,8 +1,10 @@
 """
 Tests of experiment functionality
 """
+from decimal import Decimal
 from unittest import TestCase
-from lms.djangoapps.experiments.utils import is_enrolled_in_course_run
+from lms.djangoapps.experiments.utils import get_course_entitlement_price_and_sku, get_program_price_and_skus, \
+    get_program_purchase_url, get_unenrolled_courses, is_enrolled_in_course_run
 from opaque_keys.edx.keys import CourseKey
 
 
@@ -10,6 +12,22 @@ class ExperimentUtilsTests(TestCase):
     """
     Tests of experiment functionality
     """
+
+    def setUp(self):
+        super(ExperimentUtilsTests, self).setUp()
+
+        # Create a course run
+        self.run_a_price = '86.00'
+        self.run_a_sku = 'B9B6D0B'
+        seat_a = {'type': 'verified', 'price': self.run_a_price, 'sku': self.run_a_sku}
+        seats = [seat_a]
+        self.course_run_a = {'status': 'published', 'seats': seats}
+
+        # Create an entitlement
+        self.entitlement_a_price = '199.23'
+        self.entitlement_a_sku = 'B37EBA0'
+        self.entitlement_a = {'mode': 'verified', 'price': self.entitlement_a_price, 'sku': self.entitlement_a_sku}
+
     def test_valid_course_run_key_enrollment(self):
         course_run = {
             'key': 'course-v1:DelftX+NGIx+RA0',
@@ -23,3 +41,104 @@ class ExperimentUtilsTests(TestCase):
         }
         enrollment_ids = {CourseKey.from_string('course-v1:DelftX+NGIx+RA0')}
         self.assertFalse(is_enrolled_in_course_run(course_run, enrollment_ids))
+
+    def test_program_url_with_no_skus(self):
+        url = get_program_purchase_url(None)
+        self.assertEqual(None, url)
+
+    def test_program_url_with_no_skus_and_no_bundle(self):
+        url = get_program_purchase_url(None, None)
+        self.assertEqual(None, url)
+
+    def test_program_url_with_single_sku(self):
+        skus = ['9FE0DE2']
+        expected_url = 'https://ecommerce.edx.org/basket/add/?sku=9FE0DE2'
+        url = get_program_purchase_url(skus)
+        self.assertEqual(expected_url, url)
+
+    def test_program_url_with_single_sku_and_bundle(self):
+        skus = ['9FE0DE2']
+        program_id = 'bef7201a-6f97-40ad-ad17-d5ea8be1eec8'
+        expected_url = 'https://ecommerce.edx.org/basket/add/?sku=9FE0DE2&bundle=' + program_id
+        url = get_program_purchase_url(skus, program_id)
+        self.assertEqual(expected_url, url)
+
+    def test_program_url_with_multiple_skus(self):
+        skus = ['9FE0DE2', 'B37EBA0', 'FDCED11']
+        expected_url = 'https://ecommerce.edx.org/basket/add/?sku=9FE0DE2&sku=B37EBA0&sku=FDCED11'
+        url = get_program_purchase_url(skus)
+        self.assertEqual(expected_url, url)
+
+    def test_program_url_with_multiple_skus_and_bundle(self):
+        skus = ['9FE0DE2', 'B37EBA0', 'FDCED11']
+        program_id = 'bef7201a-6f97-40ad-ad17-d5ea8be1eec8'
+        expected_url = 'https://ecommerce.edx.org/basket/add/?sku=9FE0DE2&sku=B37EBA0&sku=FDCED11&bundle=' + program_id
+        url = get_program_purchase_url(skus, program_id)
+        self.assertEqual(expected_url, url)
+
+    def test_program_price_and_skus_for_empty_courses(self):
+        price, skus = get_program_price_and_skus([])
+        self.assertEqual(None, price)
+        self.assertEqual(None, skus)
+
+    def test_unenrolled_courses_for_empty_courses(self):
+        unenrolled_courses = get_unenrolled_courses([], [])
+        self.assertEqual([], unenrolled_courses)
+
+    def test_unenrolled_courses_for_single_course(self):
+        course = {'key': 'UQx+ENGY1x'}
+        courses_in_program = [course]
+        user_enrollments = []
+
+        unenrolled_courses = get_unenrolled_courses(courses_in_program, user_enrollments)
+        expected_unenrolled_courses = [course]
+        self.assertEqual(expected_unenrolled_courses, unenrolled_courses)
+
+    def test_price_and_sku_from_empty_course(self):
+        course = {}
+
+        price, sku = get_course_entitlement_price_and_sku(course)
+        self.assertEqual(None, price)
+        self.assertEqual(None, sku)
+
+    def test_price_and_sku_from_entitlement(self):
+        entitlements = [self.entitlement_a]
+        course = {'key': 'UQx+ENGY1x', 'entitlements': entitlements}
+
+        price, sku = get_course_entitlement_price_and_sku(course)
+        self.assertEqual(self.entitlement_a_price, price)
+        self.assertEqual(self.entitlement_a_sku, sku)
+
+    def test_price_and_sku_from_course_run(self):
+        course_runs = [self.course_run_a]
+        course = {'key': 'UQx+ENGY1x', 'course_runs': course_runs}
+
+        price, sku = get_course_entitlement_price_and_sku(course)
+        expected_price = Decimal(self.run_a_price)
+        self.assertEqual(expected_price, price)
+        self.assertEqual(self.run_a_sku, sku)
+
+    def test_price_and_sku_from_course(self):
+        entitlements = [self.entitlement_a]
+        course_a = {'key': 'UQx+ENGYCAPx', 'entitlements': entitlements}
+        courses = [course_a]
+
+        price, skus = get_program_price_and_skus(courses)
+        expected_price = u'$199.23'
+        self.assertEqual(expected_price, price)
+        self.assertEqual(1, len(skus))
+        self.assertIn(self.entitlement_a_sku, skus)
+
+    def test_price_and_sku_from_multiple_courses(self):
+        entitlements = [self.entitlement_a]
+        course_runs = [self.course_run_a]
+        course_a = {'key': 'UQx+ENGY1x', 'course_runs': course_runs}
+        course_b = {'key': 'UQx+ENGYCAPx', 'entitlements': entitlements}
+        courses = [course_a, course_b]
+
+        price, skus = get_program_price_and_skus(courses)
+        expected_price = u'$285.23'
+        self.assertEqual(expected_price, price)
+        self.assertEqual(2, len(skus))
+        self.assertIn(self.run_a_sku, skus)
+        self.assertIn(self.entitlement_a_sku, skus)
diff --git a/lms/djangoapps/experiments/utils.py b/lms/djangoapps/experiments/utils.py
index 7bb349dff5cce22833fb9332c01807f988d9026c..bd83d6b240762dc5a398058cb89c5cdcd7cb9f1b 100644
--- a/lms/djangoapps/experiments/utils.py
+++ b/lms/djangoapps/experiments/utils.py
@@ -5,9 +5,11 @@ Utilities to facilitate experimentation
 import hashlib
 import re
 import logging
+from decimal import Decimal
 from student.models import CourseEnrollment
 from django_comment_common.models import Role
-from course_modes.models import get_cosmetic_verified_display_price
+from django.utils.timezone import now
+from course_modes.models import get_cosmetic_verified_display_price, format_course_price
 from courseware.access import has_staff_access_to_preview_mode
 from courseware.date_summary import verified_upgrade_deadline_link, verified_upgrade_link_is_valid
 from xmodule.partitions.partitions_service import get_user_partition_groups, get_all_partitions_for_course
@@ -37,6 +39,24 @@ PROGRAM_INFO_FLAG = WaffleFlag(
     flag_name=u'add_programs',
     flag_undefined_default=False
 )
+
+# .. feature_toggle_name: experiments.add_program_price
+# .. feature_toggle_type: flag
+# .. feature_toggle_default: False
+# .. feature_toggle_description: Toggle for adding the current course's program price and sku information to user
+#                                metadata
+# .. feature_toggle_category: experiments
+# .. feature_toggle_use_cases: monitored_rollout
+# .. feature_toggle_creation_date: 2019-3-12
+# .. feature_toggle_expiration_date: None
+# .. feature_toggle_warnings: None
+# .. feature_toggle_tickets: REVEM-118, REVEM-206
+# .. feature_toggle_status: supported
+PROGRAM_PRICE_FLAG = WaffleFlag(
+    waffle_namespace=WaffleFlagNamespace(name=u'experiments'),
+    flag_name=u'add_program_price',
+    flag_undefined_default=False
+)
 # TODO: clean up as part of REVEM-199 (END)
 
 
@@ -78,14 +98,96 @@ def check_and_get_upgrade_link_and_date(user, enrollment=None, course=None):
 
 
 # TODO: clean up as part of REVEM-199 (START)
-def is_enrolled_in_all_courses_in_program(courses_in_program, user_enrollments):
+def get_program_purchase_url(skus, bundle_id=None):
+    """
+    Return a url that will allow the purchase of the courses with these skus
+    """
+    if not skus:
+        return None
+
+    url = 'https://ecommerce.edx.org/basket/add/?'
+    for sku in skus:
+        url += 'sku=' + sku + '&'
+
+    if bundle_id:
+        url += 'bundle=' + bundle_id
+    else:
+        # Remove trailing & from the skus
+        url = url[:-1]
+    return url
+
+
+def get_program_price_and_skus(courses):
+    """
+    Get the total program price and purchase skus from these courses in the program
+    """
+    program_price = 0
+    skus = []
+
+    for course in courses:
+        course_price, course_sku = get_course_entitlement_price_and_sku(course)
+        if course_price is not None and course_sku is not None:
+            program_price = Decimal(program_price) + Decimal(course_price)
+            skus.append(course_sku)
+
+    if program_price <= 0:
+        program_price = None
+        skus = None
+    else:
+        program_price = format_course_price(program_price)
+        program_price = unicode(program_price)
+
+    return program_price, skus
+
+
+def get_course_entitlement_price_and_sku(course):
+    """
+    Get the entitlement price and sku from this course.
+    Try to get them from the first non-expired, verified entitlement that has a price and a sku. If that doesn't work,
+    fall back to the first non-expired, verified course run that has a price and a sku.
+    """
+    for entitlement in course.get('entitlements', []):
+        if entitlement.get('mode') == 'verified' and entitlement['price'] and entitlement['sku']:
+            expires = entitlement.get('expires')
+            if not expires or expires > now():
+                return entitlement['price'], entitlement['sku']
+
+    course_runs = course.get('course_runs', [])
+    published_course_runs = [run for run in course_runs if run['status'] == 'published']
+    for published_course_run in published_course_runs:
+        for seat in published_course_run['seats']:
+            if seat.get('type') == 'verified' and seat['price'] and seat['sku']:
+                price = Decimal(seat.get('price'))
+                return price, seat.get('sku')
+
+    return None, None
+
+
+def get_unenrolled_courses(courses, user_enrollments):
+    """
+    Given a list of courses and a list of user enrollments, return the courses in which the user is not enrolled.
+    Depending on the enrollments that are passed in, this method can be used to determine the courses in a program in
+    which the user has not yet enrolled or the courses in a program for which the user has not yet purchased a
+    certificate.
+    """
+    # Get the enrollment course ids here, so we don't need to loop through them for every course run
+    enrollment_course_ids = {enrollment.course_id for enrollment in user_enrollments}
+    unenrolled_courses = []
+
+    for course in courses:
+        if not is_enrolled_in_course(course, enrollment_course_ids):
+            unenrolled_courses.append(course)
+    return unenrolled_courses
+
+
+def is_enrolled_in_all_courses(courses, user_enrollments):
     """
-    Determine if the user is enrolled in all courses in this program
+    Determine if the user is enrolled in all of the courses
     """
     # Get the enrollment course ids here, so we don't need to loop through them for every course run
     enrollment_course_ids = {enrollment.course_id for enrollment in user_enrollments}
 
-    for course in courses_in_program:
+    for course in courses:
         if not is_enrolled_in_course(course, enrollment_course_ids):
             # User is not enrolled in this course, meaning they are not enrolled in all courses in the program
             return False
@@ -148,18 +250,40 @@ def get_experiment_user_metadata_context(course, user):
                 # A course can be in multiple programs, but we're just grabbing the first one
                 program = programs[0]
                 complete_enrollment = False
+                has_courses_left_to_purchase = False
                 total_courses = None
                 courses = program.get('courses')
+                courses_left_to_purchase_price = None
+                courses_left_to_purchase_url = None
+                program_uuid = program.get('uuid')
                 if courses is not None:
                     total_courses = len(courses)
-                    complete_enrollment = is_enrolled_in_all_courses_in_program(courses, user_enrollments)
+                    complete_enrollment = is_enrolled_in_all_courses(courses, user_enrollments)
+
+                    if PROGRAM_PRICE_FLAG.is_enabled():
+                        # Get the price and purchase URL of the program courses the user has yet to purchase. Say a
+                        # program has 3 courses (A, B and C), and the user previously purchased a certificate for A.
+                        # The user is enrolled in audit mode for B. The "left to purchase price" should be the price of
+                        # B+C.
+                        non_audit_enrollments = [enrollment for enrollment in user_enrollments if enrollment not in
+                                                 audit_enrollments]
+                        courses_left_to_purchase = get_unenrolled_courses(courses, non_audit_enrollments)
+                        if courses_left_to_purchase:
+                            has_courses_left_to_purchase = True
+                        courses_left_to_purchase_price, courses_left_to_purchase_skus = get_program_price_and_skus(
+                            courses_left_to_purchase)
+                        courses_left_to_purchase_url = get_program_purchase_url(courses_left_to_purchase_skus,
+                                                                                program_uuid)
 
                 program_key = {
-                    'uuid': program.get('uuid'),
+                    'uuid': program_uuid,
                     'title': program.get('title'),
                     'marketing_url': program.get('marketing_url'),
                     'total_courses': total_courses,
                     'complete_enrollment': complete_enrollment,
+                    'has_courses_left_to_purchase': has_courses_left_to_purchase,
+                    'courses_left_to_purchase_price': courses_left_to_purchase_price,
+                    'courses_left_to_purchase_url': courses_left_to_purchase_url,
                 }
         # TODO: clean up as part of REVEM-199 (END)
         enrollment = CourseEnrollment.objects.select_related(