diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py
index cd51c4a5c7f55ab3692a0b3ca2dd046aa37d399b..f291d196e3c3f77cbac610f42ac5d675d59aab89 100644
--- a/common/djangoapps/student/views.py
+++ b/common/djangoapps/student/views.py
@@ -127,6 +127,7 @@ from openedx.core.djangoapps.programs.models import ProgramsApiConfig
 from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
 from openedx.core.djangoapps.theming import helpers as theming_helpers
 from openedx.core.djangoapps.user_api.preferences import api as preferences_api
+from openedx.core.djangoapps.catalog.utils import get_programs_data
 
 
 log = logging.getLogger("edx.student")
@@ -173,6 +174,7 @@ def index(request, extra_context=None, user=AnonymousUser()):
     if extra_context is None:
         extra_context = {}
 
+    programs_list = []
     courses = get_courses(user)
 
     if configuration_helpers.get_value(
@@ -206,6 +208,16 @@ def index(request, extra_context=None, user=AnonymousUser()):
     # Insert additional context for use in the template
     context.update(extra_context)
 
+    # Getting all the programs from course-catalog service. The programs_list is being added to the context but it's
+    # not being used currently in lms/templates/index.html. To use this list, you need to create a custom theme that
+    # overrides index.html. The modifications to index.html to display the programs will be done after the support
+    # for edx-pattern-library is added.
+    if configuration_helpers.get_value("DISPLAY_PROGRAMS_ON_MARKETING_PAGES",
+                                       settings.FEATURES.get("DISPLAY_PROGRAMS_ON_MARKETING_PAGES")):
+        programs_list = get_programs_data(user)
+
+    context["programs_list"] = programs_list
+
     return render_to_response('index.html', context)
 
 
diff --git a/lms/djangoapps/branding/tests/test_page.py b/lms/djangoapps/branding/tests/test_page.py
index 230eec9f694a398c6867df8109c6d653e61a2233..ef2b4cd658ea82de65ba936da6ca008640027c8b 100644
--- a/lms/djangoapps/branding/tests/test_page.py
+++ b/lms/djangoapps/branding/tests/test_page.py
@@ -2,6 +2,7 @@
 Tests for branding page
 """
 
+import mock
 import datetime
 
 from django.conf import settings
@@ -287,3 +288,37 @@ class IndexPageCourseCardsSortingTests(ModuleStoreTestCase):
         self.assertEqual(context['courses'][0].id, self.starting_later.id)
         self.assertEqual(context['courses'][1].id, self.starting_earlier.id)
         self.assertEqual(context['courses'][2].id, self.course_with_default_start_date.id)
+
+
+@attr(shard=1)
+class IndexPageProgramsTests(ModuleStoreTestCase):
+    """
+    Tests for Programs List in Marketing Pages.
+    """
+    @patch.dict('django.conf.settings.FEATURES', {'DISPLAY_PROGRAMS_ON_MARKETING_PAGES': False})
+    def test_get_programs_not_called(self):
+        with mock.patch("student.views.get_programs_data") as patched_get_programs_data:
+            # check the /dashboard
+            response = self.client.get('/')
+            self.assertEqual(response.status_code, 200)
+            self.assertEqual(patched_get_programs_data.call_count, 0)
+
+        with mock.patch("courseware.views.views.get_programs_data") as patched_get_programs_data:
+            # check the /courses view
+            response = self.client.get(reverse('branding.views.courses'))
+            self.assertEqual(response.status_code, 200)
+            self.assertEqual(patched_get_programs_data.call_count, 0)
+
+    @patch.dict('django.conf.settings.FEATURES', {'DISPLAY_PROGRAMS_ON_MARKETING_PAGES': True})
+    def test_get_programs_called(self):
+        with mock.patch("student.views.get_programs_data") as patched_get_programs_data:
+            # check the /dashboard
+            response = self.client.get('/')
+            self.assertEqual(response.status_code, 200)
+            self.assertEqual(patched_get_programs_data.call_count, 1)
+
+        with mock.patch("courseware.views.views.get_programs_data") as patched_get_programs_data:
+            # check the /courses view
+            response = self.client.get(reverse('branding.views.courses'))
+            self.assertEqual(response.status_code, 200)
+            self.assertEqual(patched_get_programs_data.call_count, 1)
diff --git a/lms/djangoapps/courseware/views/views.py b/lms/djangoapps/courseware/views/views.py
index f4f4ba42b6f290f3946b10f13a9f386af2bcf73f..b28c2162c5eaf762af9e8a6e4a90f83a372cbbd7 100644
--- a/lms/djangoapps/courseware/views/views.py
+++ b/lms/djangoapps/courseware/views/views.py
@@ -34,18 +34,22 @@ from opaque_keys.edx.keys import CourseKey, UsageKey
 from opaque_keys.edx.locations import SlashSeparatedCourseKey
 from rest_framework import status
 from lms.djangoapps.instructor.views.api import require_global_staff
+from lms.djangoapps.ccx.utils import prep_course_for_grading
+from lms.djangoapps.grades.new.course_grade import CourseGradeFactory
+from lms.djangoapps.instructor.enrollment import uses_shib
+from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
+from lms.djangoapps.ccx.custom_exception import CCXLocatorValidationException
 
+from openedx.core.djangoapps.catalog.utils import get_programs_data
 import shoppingcart
 import survey.utils
 import survey.views
-from lms.djangoapps.ccx.utils import prep_course_for_grading
 from certificates import api as certs_api
 from certificates.models import CertificateStatuses
 from openedx.core.djangoapps.models.course_details import CourseDetails
 from commerce.utils import EcommerceService
 from enrollment.api import add_enrollment
 from course_modes.models import CourseMode
-from lms.djangoapps.grades.new.course_grade import CourseGradeFactory
 from courseware.access import has_access, has_ccx_coach_role, _adjust_start_date_for_beta_testers
 from courseware.access_response import StartDateError
 from courseware.access_utils import in_preview_mode
@@ -67,8 +71,6 @@ from courseware.models import StudentModule, BaseStudentModuleHistory
 from courseware.url_helpers import get_redirect_url, get_redirect_url_for_global_staff
 from courseware.user_state_client import DjangoXBlockUserStateClient
 from edxmako.shortcuts import render_to_response, render_to_string, marketing_link
-from lms.djangoapps.instructor.enrollment import uses_shib
-from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
 from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
 from openedx.core.djangoapps.coursetalk.helpers import inject_coursetalk_keys_into_context
 from openedx.core.djangoapps.credit.api import (
@@ -91,11 +93,9 @@ from xmodule.modulestore.django import modulestore
 from xmodule.modulestore.exceptions import ItemNotFoundError, NoPathToItem
 from xmodule.tabs import CourseTabList
 from xmodule.x_module import STUDENT_VIEW
-from lms.djangoapps.ccx.custom_exception import CCXLocatorValidationException
 from ..entrance_exams import user_must_complete_entrance_exam
 from ..module_render import get_module_for_descriptor, get_module, get_module_by_usage_id
 
-
 log = logging.getLogger("edx.courseware")
 
 
@@ -136,21 +136,32 @@ def courses(request):
     Render "find courses" page.  The course selection work is done in courseware.courses.
     """
     courses_list = []
+    programs_list = []
     course_discovery_meanings = getattr(settings, 'COURSE_DISCOVERY_MEANINGS', {})
     if not settings.FEATURES.get('ENABLE_COURSE_DISCOVERY'):
         courses_list = get_courses(request.user)
 
-        if configuration_helpers.get_value(
-                "ENABLE_COURSE_SORTING_BY_START_DATE",
-                settings.FEATURES["ENABLE_COURSE_SORTING_BY_START_DATE"]
-        ):
+        if configuration_helpers.get_value("ENABLE_COURSE_SORTING_BY_START_DATE",
+                                           settings.FEATURES["ENABLE_COURSE_SORTING_BY_START_DATE"]):
             courses_list = sort_by_start_date(courses_list)
         else:
             courses_list = sort_by_announcement(courses_list)
 
+    # Getting all the programs from course-catalog service. The programs_list is being added to the context but it's
+    # not being used currently in courseware/courses.html. To use this list, you need to create a custom theme that
+    # overrides courses.html. The modifications to courses.html to display the programs will be done after the support
+    # for edx-pattern-library is added.
+    if configuration_helpers.get_value("DISPLAY_PROGRAMS_ON_MARKETING_PAGES",
+                                       settings.FEATURES.get("DISPLAY_PROGRAMS_ON_MARKETING_PAGES")):
+        programs_list = get_programs_data(request.user)
+
     return render_to_response(
         "courseware/courses.html",
-        {'courses': courses_list, 'course_discovery_meanings': course_discovery_meanings}
+        {
+            'courses': courses_list,
+            'course_discovery_meanings': course_discovery_meanings,
+            'programs_list': programs_list
+        }
     )
 
 
diff --git a/lms/envs/common.py b/lms/envs/common.py
index f380bb25774cb4983cfb10cd543807323e96976c..1d6eefae742723bd75896d790ebe78236765f62b 100644
--- a/lms/envs/common.py
+++ b/lms/envs/common.py
@@ -249,11 +249,15 @@ FEATURES = {
     # False to not redirect the user
     'ALWAYS_REDIRECT_HOMEPAGE_TO_DASHBOARD_FOR_AUTHENTICATED_USER': True,
 
-    # When a user goes to the homepage ('/') the user see the
+    # When a user goes to the homepage ('/') the user sees the
     # courses listed in the announcement dates order - this is default Open edX behavior.
     # Set to True to change the course sorting behavior by their start dates, latest first.
     'ENABLE_COURSE_SORTING_BY_START_DATE': True,
 
+    # When set to True, a list of programs is displayed along with the list of courses
+    # when the user visits the homepage or the find courses page.
+    'DISPLAY_PROGRAMS_ON_MARKETING_PAGES': False,
+
     # Expose Mobile REST API. Note that if you use this, you must also set
     # ENABLE_OAUTH2_PROVIDER to True
     'ENABLE_MOBILE_REST_API': False,
diff --git a/openedx/core/djangoapps/catalog/migrations/0002_catalogintegration_username.py b/openedx/core/djangoapps/catalog/migrations/0002_catalogintegration_username.py
new file mode 100644
index 0000000000000000000000000000000000000000..26218c13bafe7ed126d4c6b9cf2c52e3a756645e
--- /dev/null
+++ b/openedx/core/djangoapps/catalog/migrations/0002_catalogintegration_username.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('catalog', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='catalogintegration',
+            name='service_username',
+            field=models.CharField(default=b'lms_catalog_service_user', help_text='Username created for Course Catalog Integration, e.g. lms_catalog_service_user.', max_length=100),
+        ),
+    ]
diff --git a/openedx/core/djangoapps/catalog/models.py b/openedx/core/djangoapps/catalog/models.py
index 1d01d90b7150c9d2cfb5e6d4a08dce8b8c1cc8a5..80e95a60d2ca1f95633bdc3993327aa0afd30349 100644
--- a/openedx/core/djangoapps/catalog/models.py
+++ b/openedx/core/djangoapps/catalog/models.py
@@ -25,6 +25,16 @@ class CatalogIntegration(ConfigurationModel):
         )
     )
 
+    service_username = models.CharField(
+        max_length=100,
+        default="lms_catalog_service_user",
+        null=False,
+        blank=False,
+        help_text=_(
+            'Username created for Course Catalog Integration, e.g. lms_catalog_service_user.'
+        )
+    )
+
     @property
     def is_cache_enabled(self):
         """Whether responses from the catalog API will be cached."""
diff --git a/openedx/core/djangoapps/catalog/tests/factories.py b/openedx/core/djangoapps/catalog/tests/factories.py
index 257cd92d5053614cb0eb6abb1d6639aac3c7b68a..3246a5d422dccc97e16a4b1c9519526bae4c7fed 100644
--- a/openedx/core/djangoapps/catalog/tests/factories.py
+++ b/openedx/core/djangoapps/catalog/tests/factories.py
@@ -70,3 +70,14 @@ class Program(factory.Factory):
     banner_image = {
         size: BannerImage() for size in ['large', 'medium', 'small', 'x-small']
     }
+
+
+class ProgramType(factory.Factory):
+    """
+    Factory for stubbing ProgramType resources from the catalog API.
+    """
+    class Meta(object):
+        model = dict
+
+    name = FuzzyText()
+    logo_image = FuzzyText(prefix='https://example.com/program/logo')
diff --git a/openedx/core/djangoapps/catalog/tests/test_utils.py b/openedx/core/djangoapps/catalog/tests/test_utils.py
index bb813ba277164e9148613d959a2d89641c3a08da..8638f8525b1a964525175501109866d2f38275a4 100644
--- a/openedx/core/djangoapps/catalog/tests/test_utils.py
+++ b/openedx/core/djangoapps/catalog/tests/test_utils.py
@@ -2,6 +2,7 @@
 Tests covering utilities for integrating with the catalog service.
 """
 import uuid
+import copy
 
 from django.core.cache import cache
 from django.test import TestCase
@@ -12,9 +13,8 @@ from opaque_keys.edx.keys import CourseKey
 from openedx.core.djangoapps.catalog import utils
 from openedx.core.djangoapps.catalog.models import CatalogIntegration
 from openedx.core.djangoapps.catalog.tests import factories, mixins
+from student.tests.factories import UserFactory, AnonymousUserFactory
 from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
-from student.tests.factories import UserFactory
-
 
 UTILS_MODULE = 'openedx.core.djangoapps.catalog.utils'
 
@@ -76,6 +76,73 @@ class TestGetPrograms(mixins.CatalogIntegrationMixin, TestCase):
         self.assert_contract(mock_get_catalog_data.call_args)
         self.assertEqual(data, programs)
 
+    def test_get_programs_anonymous_user(self, _mock_cache, mock_get_catalog_data):
+        programs = [factories.Program() for __ in range(3)]
+        mock_get_catalog_data.return_value = programs
+
+        anonymous_user = AnonymousUserFactory()
+
+        # The user is an Anonymous user but the Catalog Service User has not been created yet.
+        data = utils.get_programs(anonymous_user)
+        # This should not return programs.
+        self.assertEqual(data, [])
+
+        UserFactory(username='lms_catalog_service_user')
+        # After creating the service user above,
+        data = utils.get_programs(anonymous_user)
+        # the programs should be returned successfully.
+        self.assertEqual(data, programs)
+
+    def test_get_program_types(self, _mock_cache, mock_get_catalog_data):
+        program_types = [factories.ProgramType() for __ in range(3)]
+        mock_get_catalog_data.return_value = program_types
+
+        # Creating Anonymous user but the Catalog Service User has not been created yet.
+        anonymous_user = AnonymousUserFactory()
+        data = utils.get_program_types(anonymous_user)
+        # This should not return programs.
+        self.assertEqual(data, [])
+
+        # Creating Catalog Service User user
+        UserFactory(username='lms_catalog_service_user')
+        data = utils.get_program_types(anonymous_user)
+        # the programs should be returned successfully.
+        self.assertEqual(data, program_types)
+
+        # Catalog integration is disabled now.
+        self.catalog_integration = self.create_catalog_integration(enabled=False)
+        data = utils.get_program_types(anonymous_user)
+        # This should not return programs.
+        self.assertEqual(data, [])
+
+    def test_get_programs_data(self, _mock_cache, mock_get_catalog_data):   # pylint: disable=unused-argument
+        programs = []
+        program_types = []
+        programs_data = []
+
+        for index in range(3):
+            # Creating the Programs and their corresponding program types.
+            type_name = "type_name_{postfix}".format(postfix=index)
+            program = factories.Program(type=type_name)
+            program_type = factories.ProgramType(name=type_name)
+
+            # Maintaining the programs, program types and program data(program+logo_image) lists.
+            programs.append(program)
+            program_types.append(program_type)
+            programs_data.append(copy.deepcopy(program))
+
+            # Adding the logo image in program data.
+            programs_data[-1]['logo_image'] = program_type["logo_image"]
+
+        with mock.patch("openedx.core.djangoapps.catalog.utils.get_programs") as patched_get_programs:
+            with mock.patch("openedx.core.djangoapps.catalog.utils.get_program_types") as patched_get_program_types:
+                # Mocked the "get_programs" and "get_program_types"
+                patched_get_programs.return_value = programs
+                patched_get_program_types.return_value = program_types
+
+                programs_data = utils.get_programs_data()
+                self.assertEqual(programs_data, programs)
+
     def test_get_one_program(self, _mock_cache, mock_get_catalog_data):
         program = factories.Program()
         mock_get_catalog_data.return_value = program
diff --git a/openedx/core/djangoapps/catalog/utils.py b/openedx/core/djangoapps/catalog/utils.py
index 44bb8f36cbc135abb258c8e57022bf9ab8b08f71..e902aa74e7e948ba2da140d818ece6b55dbf0aca 100644
--- a/openedx/core/djangoapps/catalog/utils.py
+++ b/openedx/core/djangoapps/catalog/utils.py
@@ -4,6 +4,7 @@ import logging
 
 from django.conf import settings
 from django.core.cache import cache
+from django.contrib.auth.models import User
 from edx_rest_api_client.client import EdxRestApiClient
 from opaque_keys.edx.keys import CourseKey
 
@@ -24,7 +25,20 @@ def create_catalog_api_client(user, catalog_integration):
     return EdxRestApiClient(catalog_integration.internal_api_url, jwt=jwt)
 
 
-def get_programs(user, uuid=None, type=None):  # pylint: disable=redefined-builtin
+def _get_service_user(user, service_username):
+    """
+    Retrieve and return the Catalog Integration Service User Object
+    if the passed user is None or anonymous
+    """
+    if not user or user.is_anonymous():
+        try:
+            user = User.objects.get(username=service_username)
+        except User.DoesNotExist:
+            user = None
+    return user
+
+
+def get_programs(user=None, uuid=None, type=None):  # pylint: disable=redefined-builtin
     """Retrieve marketable programs from the catalog service.
 
     Keyword Arguments:
@@ -36,8 +50,11 @@ def get_programs(user, uuid=None, type=None):  # pylint: disable=redefined-built
         dict, if a specific program is requested.
     """
     catalog_integration = CatalogIntegration.current()
-
     if catalog_integration.enabled:
+        user = _get_service_user(user, catalog_integration.service_username)
+        if not user:
+            return []
+
         api = create_catalog_api_client(user, catalog_integration)
 
         cache_key = '{base}.programs{type}'.format(
@@ -66,6 +83,46 @@ def get_programs(user, uuid=None, type=None):  # pylint: disable=redefined-built
         return []
 
 
+def get_program_types(user=None):  # pylint: disable=redefined-builtin
+    """Retrieve all program types from the catalog service.
+
+    Returns:
+        list of dict, representing program types.
+    """
+    catalog_integration = CatalogIntegration.current()
+    if catalog_integration.enabled:
+        user = _get_service_user(user, catalog_integration.service_username)
+        if not user:
+            return []
+
+        api = create_catalog_api_client(user, catalog_integration)
+        cache_key = '{base}.program_types'.format(base=catalog_integration.CACHE_KEY)
+
+        return get_edx_api_data(
+            catalog_integration,
+            user,
+            'program_types',
+            cache_key=cache_key if catalog_integration.is_cache_enabled else None,
+            api=api
+        )
+    else:
+        return []
+
+
+def get_programs_data(user=None):
+    """Return the list of Programs after adding the ProgramType Logo Image"""
+
+    programs_list = get_programs(user)
+    program_types = get_program_types(user)
+
+    program_types_lookup_dict = {program_type["name"]: program_type for program_type in program_types}
+
+    for program in programs_list:
+        program["logo_image"] = program_types_lookup_dict[program["type"]]["logo_image"]
+
+    return programs_list
+
+
 def munge_catalog_program(catalog_program):
     """Make a program from the catalog service look like it came from the programs service.