diff --git a/app/assets/javascripts/ci/pipelines_page/components/pipeline_url.vue b/app/assets/javascripts/ci/pipelines_page/components/pipeline_url.vue
index 1173d137a1b625a2c1689c6d37c0dccf5b5178ff..ee299ef46f66ada137497c843af6b9b43005a7fc 100644
--- a/app/assets/javascripts/ci/pipelines_page/components/pipeline_url.vue
+++ b/app/assets/javascripts/ci/pipelines_page/components/pipeline_url.vue
@@ -120,8 +120,24 @@ export default {
     commitTitle() {
       return this.pipeline?.commit?.title;
     },
-    pipelineName() {
-      return this.pipeline?.name;
+    pipelineIdentifier() {
+      const { name, path, pipeline_schedule: pipelineSchedule } = this.pipeline || {};
+
+      if (pipelineSchedule) {
+        return {
+          text: pipelineSchedule.description,
+          link: pipelineSchedule.path,
+        };
+      }
+
+      if (name) {
+        return {
+          text: name,
+          link: path,
+        };
+      }
+
+      return false;
     },
   },
   methods: {
@@ -133,17 +149,27 @@ export default {
 </script>
 <template>
   <div class="pipeline-tags" data-testid="pipeline-url-table-cell">
-    <div v-if="pipelineName" class="gl-mb-2" data-testid="pipeline-name-container">
+    <div v-if="pipelineIdentifier" class="gl-mb-2" data-testid="pipeline-identifier-container">
       <span class="gl-flex">
-        <tooltip-on-truncate :title="pipelineName" class="gl-grow gl-truncate gl-text-gray-900">
-          <gl-link :href="pipeline.path" class="!gl-text-link" data-testid="pipeline-url-link">{{
-            pipelineName
-          }}</gl-link>
+        <tooltip-on-truncate
+          :title="pipelineIdentifier.text"
+          class="gl-grow gl-truncate gl-text-gray-900"
+        >
+          <gl-link
+            :href="pipelineIdentifier.link"
+            class="!gl-text-link"
+            data-testid="pipeline-identifier-link"
+            >{{ pipelineIdentifier.text }}</gl-link
+          >
         </tooltip-on-truncate>
       </span>
     </div>
 
-    <div v-if="!pipelineName" class="commit-title gl-mb-2" data-testid="commit-title-container">
+    <div
+      v-if="!pipelineIdentifier"
+      class="commit-title gl-mb-2"
+      data-testid="commit-title-container"
+    >
       <span v-if="commitTitle" class="gl-flex">
         <tooltip-on-truncate
           :title="commitTitle"
@@ -162,6 +188,7 @@ export default {
         __("Can't find HEAD commit for this branch")
       }}</span>
     </div>
+
     <div class="gl-mb-2">
       <gl-link
         :href="pipeline.path"
@@ -200,6 +227,7 @@ export default {
           >
         </tooltip-on-truncate>
       </div>
+
       <div class="gl-inline-block gl-rounded-base gl-bg-gray-50 gl-px-2 gl-text-sm gl-text-default">
         <gl-icon
           v-gl-tooltip
@@ -217,6 +245,7 @@ export default {
           >{{ commitShortSha }}</gl-link
         >
       </div>
+
       <user-avatar-link
         v-if="commitAuthor"
         :link-href="commitAuthor.path"
diff --git a/app/serializers/ci/pipeline_entity.rb b/app/serializers/ci/pipeline_entity.rb
index 10a3330b923312afb5a0c1c349a62e161a7dcdf7..70cc499386ddd72a5e6a83de85e448dd9a584705 100644
--- a/app/serializers/ci/pipeline_entity.rb
+++ b/app/serializers/ci/pipeline_entity.rb
@@ -96,6 +96,8 @@ class Ci::PipelineEntity < Grape::Entity
     pipeline.failed_builds.size
   end
 
+  expose :pipeline_schedule, using: Ci::PipelineScheduleEntity
+
   private
 
   alias_method :pipeline, :object
diff --git a/app/serializers/ci/pipeline_schedule_entity.rb b/app/serializers/ci/pipeline_schedule_entity.rb
new file mode 100644
index 0000000000000000000000000000000000000000..b68730ddfe4c2101c1aaccab90b52167c7fc6689
--- /dev/null
+++ b/app/serializers/ci/pipeline_schedule_entity.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Ci
+  class PipelineScheduleEntity < Grape::Entity
+    include RequestAwareEntity
+
+    expose :id
+    expose :description
+    expose :path do |schedule|
+      pipeline_schedules_path(schedule.project)
+    end
+  end
+end
diff --git a/app/serializers/pipeline_serializer.rb b/app/serializers/pipeline_serializer.rb
index 0a14988b08d522645e215267cc736fbfe3eb14c3..4a42eeaed5e372070711c28cacc3d6483a28dd97 100644
--- a/app/serializers/pipeline_serializer.rb
+++ b/app/serializers/pipeline_serializer.rb
@@ -33,6 +33,7 @@ def represent_stages(resource)
   def preloaded_relations(preload_statuses: true, preload_downstream_statuses: true, **)
     [
       :pipeline_metadata,
+      :pipeline_schedule,
       :cancelable_statuses,
       :retryable_builds,
       :stages,
diff --git a/spec/frontend/ci/pipelines_page/components/pipeline_url_spec.js b/spec/frontend/ci/pipelines_page/components/pipeline_url_spec.js
index 46e836cc101ff0bf52b8ee822f99301bf7bf55b0..d9afaad784c4c0a85230afbe21d1da3337597e53 100644
--- a/spec/frontend/ci/pipelines_page/components/pipeline_url_spec.js
+++ b/spec/frontend/ci/pipelines_page/components/pipeline_url_spec.js
@@ -8,7 +8,7 @@ import {
   mockPipeline,
   mockPipelineBranch,
   mockPipelineTag,
-} from 'jest/ci/pipeline_details/mock_data';
+} from '../../pipeline_details/mock_data';
 
 const projectPath = 'test/test';
 
@@ -18,6 +18,7 @@ describe('Pipeline Url Component', () => {
 
   const findTableCell = () => wrapper.findByTestId('pipeline-url-table-cell');
   const findPipelineUrlLink = () => wrapper.findByTestId('pipeline-url-link');
+  const findPipelineIdentifierLink = () => wrapper.findByTestId('pipeline-identifier-link');
   const findRefName = () => wrapper.findByTestId('merge-request-ref');
   const findCommitShortSha = () => wrapper.findByTestId('commit-short-sha');
   const findCommitIcon = () => wrapper.findByTestId('commit-icon');
@@ -25,7 +26,8 @@ describe('Pipeline Url Component', () => {
   const findCommitRefName = () => wrapper.findByTestId('commit-ref-name');
 
   const findCommitTitleContainer = () => wrapper.findByTestId('commit-title-container');
-  const findPipelineNameContainer = () => wrapper.findByTestId('pipeline-name-container');
+  const findPipelineIdentifierContainer = () =>
+    wrapper.findByTestId('pipeline-identifier-container');
   const findCommitTitle = (commitWrapper) => commitWrapper.find('[data-testid="commit-title"]');
 
   const defaultProps = { ...mockPipeline(projectPath), refClass: 'gl-text-black' };
@@ -46,20 +48,43 @@ describe('Pipeline Url Component', () => {
     createComponent();
 
     expect(findPipelineUrlLink().attributes('href')).toBe('foo');
-
     expect(findPipelineUrlLink().text()).toBe('#1');
   });
 
-  it('should render the pipeline name instead of commit title', () => {
-    createComponent(merge(mockPipeline(projectPath), { pipeline: { name: 'Build pipeline' } }));
+  it('should render the pipeline schedule identifier instead of pipeline name', () => {
+    createComponent(
+      merge(mockPipeline(projectPath), {
+        pipeline: {
+          name: 'Build pipeline',
+          pipeline_schedule: { id: 1, description: 'Schedule', path: 'schedule/path' },
+        },
+      }),
+    );
+
+    expect(findCommitTitleContainer().exists()).toBe(false);
+    expect(findPipelineIdentifierContainer().exists()).toBe(true);
+    expect(findRefName().exists()).toBe(true);
+    expect(findCommitShortSha().exists()).toBe(true);
+    expect(findPipelineIdentifierLink().text()).toBe('Schedule');
+    expect(findPipelineIdentifierLink().attributes('href')).toBe('schedule/path');
+  });
+
+  it('should render the pipeline name identifier instead of commit title', () => {
+    createComponent(
+      merge(mockPipeline(projectPath), {
+        pipeline: { name: 'Build pipeline', pipeline_schedule: null },
+      }),
+    );
 
     expect(findCommitTitleContainer().exists()).toBe(false);
-    expect(findPipelineNameContainer().exists()).toBe(true);
+    expect(findPipelineIdentifierContainer().exists()).toBe(true);
     expect(findRefName().exists()).toBe(true);
     expect(findCommitShortSha().exists()).toBe(true);
+    expect(findPipelineIdentifierLink().text()).toBe('Build pipeline');
+    expect(findPipelineIdentifierLink().attributes('href')).toBe('foo');
   });
 
-  it('should render the commit title when pipeline has no name', () => {
+  it('should render the commit title when pipeline has no identifier', () => {
     createComponent();
 
     const commitWrapper = findCommitTitleContainer();
@@ -67,7 +92,8 @@ describe('Pipeline Url Component', () => {
     expect(findCommitTitle(commitWrapper).exists()).toBe(true);
     expect(findRefName().exists()).toBe(true);
     expect(findCommitShortSha().exists()).toBe(true);
-    expect(findPipelineNameContainer().exists()).toBe(false);
+    expect(findPipelineIdentifierContainer().exists()).toBe(false);
+    expect(findPipelineIdentifierLink().exists()).toBe(false);
   });
 
   it('should pass the refClass prop to merge request link', () => {
diff --git a/spec/serializers/ci/pipeline_entity_spec.rb b/spec/serializers/ci/pipeline_entity_spec.rb
index e4ac8488c8c3b387439b7aac17053404bd010065..0cff0c6a8962776ba224471a6a984da7dd0cebf2 100644
--- a/spec/serializers/ci/pipeline_entity_spec.rb
+++ b/spec/serializers/ci/pipeline_entity_spec.rb
@@ -300,5 +300,26 @@
         expect(subject[:coverage]).to eq('35.00')
       end
     end
+
+    context 'when pipeline has a schedule' do
+      let_it_be(:pipeline_schedule) { create(:ci_pipeline_schedule, :nightly, project: project) }
+      let_it_be(:pipeline) { create(:ci_pipeline, pipeline_schedule: pipeline_schedule, project: project) }
+
+      it 'exposes the schedule' do
+        expect(subject[:pipeline_schedule]).to eq({
+          id: pipeline_schedule.id,
+          description: pipeline_schedule.description,
+          path: pipeline_schedules_path(pipeline_schedule.project)
+        })
+      end
+    end
+
+    context 'when pipeline has no schedule' do
+      let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+
+      it 'is nil' do
+        expect(subject[:pipeline_schedule]).to be_nil
+      end
+    end
   end
 end
diff --git a/spec/serializers/ci/pipeline_schedule_entity_spec.rb b/spec/serializers/ci/pipeline_schedule_entity_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..21d0d510bd0fd24ae6e635a1b4682215c0c502b5
--- /dev/null
+++ b/spec/serializers/ci/pipeline_schedule_entity_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::PipelineScheduleEntity, feature_category: :continuous_integration do
+  include Gitlab::Routing
+
+  let_it_be(:project) { build_stubbed(:project) }
+  let_it_be(:pipeline_schedule) { build_stubbed(:ci_pipeline_schedule, :nightly, project: project) }
+
+  let(:request) { instance_double(ActionDispatch::Request) }
+  let(:entity) { described_class.new(pipeline_schedule, request: request) }
+
+  subject(:data) { entity.as_json }
+
+  it { is_expected.to include(:id) }
+  it { is_expected.to include(:description) }
+  it { is_expected.to include(:path) }
+
+  it { expect(data[:id]).to eq(pipeline_schedule.id) }
+  it { expect(data[:description]).to eq(pipeline_schedule.description) }
+  it { expect(data[:path]).to eq(pipeline_schedules_path(pipeline_schedule.project)) }
+end