diff --git a/ee/config/events/execute_job_pipeline_execution_policy.yml b/ee/config/events/execute_job_pipeline_execution_policy.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6f66fd47c0f0483250ce1b532abcaac7ce1ba908
--- /dev/null
+++ b/ee/config/events/execute_job_pipeline_execution_policy.yml
@@ -0,0 +1,14 @@
+---
+description: Job executed by pipeline execution policy
+internal_events: true
+action: execute_job_pipeline_execution_policy
+identifiers:
+- project
+- namespace
+product_group: security_policies
+milestone: '17.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159957
+distributions:
+- ee
+tiers:
+- ultimate
diff --git a/ee/config/metrics/counts_28d/count_total_execute_job_pipeline_execution_policy_monthly.yml b/ee/config/metrics/counts_28d/count_total_execute_job_pipeline_execution_policy_monthly.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ad265b99d323e01a81323419923ebb5f65c033a4
--- /dev/null
+++ b/ee/config/metrics/counts_28d/count_total_execute_job_pipeline_execution_policy_monthly.yml
@@ -0,0 +1,18 @@
+---
+key_path: counts.count_total_execute_job_pipeline_execution_policy_monthly
+description: Monthly count of jobs executed by pipeline execution policies
+product_group: security_policies
+performance_indicator_type: []
+value_type: number
+status: active
+milestone: '17.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159957
+time_frame: 28d
+data_source: internal_events
+data_category: optional
+distribution:
+- ee
+tier:
+- ultimate
+events:
+- name: execute_job_pipeline_execution_policy
diff --git a/ee/config/metrics/counts_7d/count_total_execute_job_pipeline_execution_policy_weekly.yml b/ee/config/metrics/counts_7d/count_total_execute_job_pipeline_execution_policy_weekly.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c9cbfb226a8fbea36f581e1c9a422cad6b0d3c0e
--- /dev/null
+++ b/ee/config/metrics/counts_7d/count_total_execute_job_pipeline_execution_policy_weekly.yml
@@ -0,0 +1,18 @@
+---
+key_path: counts.count_total_execute_job_pipeline_execution_policy_weekly
+description: Weekly count of jobs executed by pipeline execution policies
+product_group: security_policies
+performance_indicator_type: []
+value_type: number
+status: active
+milestone: '17.3'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159957
+time_frame: 7d
+data_source: internal_events
+data_category: optional
+distribution:
+- ee
+tier:
+- ultimate
+events:
+- name: execute_job_pipeline_execution_policy
diff --git a/ee/lib/gitlab/ci/pipeline/pipeline_execution_policies/jobs_merger.rb b/ee/lib/gitlab/ci/pipeline/pipeline_execution_policies/jobs_merger.rb
index 670d869b4a8775a2d3da5fe80f27ef5e20386826..1dca87a0cd55ed0b06b81e084bd0ce218642ecf6 100644
--- a/ee/lib/gitlab/ci/pipeline/pipeline_execution_policies/jobs_merger.rb
+++ b/ee/lib/gitlab/ci/pipeline/pipeline_execution_policies/jobs_merger.rb
@@ -14,12 +14,15 @@ module PipelineExecutionPolicies
 
         class JobsMerger
           include ::Gitlab::Utils::StrongMemoize
+          include ::Gitlab::InternalEventsTracking
 
           def initialize(pipeline:, pipeline_execution_policies:, declared_stages:)
             @pipeline = pipeline
             @pipeline_execution_policies = pipeline_execution_policies
             @declared_stages = declared_stages
             @pipeline_stages_by_name = pipeline.stages.index_by(&:name)
+            @project = pipeline.project
+            @namespace = project.namespace
           end
 
           def execute
@@ -32,7 +35,8 @@ def execute
 
           private
 
-          attr_reader :pipeline, :pipeline_execution_policies, :declared_stages, :pipeline_stages_by_name
+          attr_reader :pipeline, :pipeline_execution_policies, :declared_stages, :pipeline_stages_by_name, :project,
+            :namespace
 
           def inject_jobs_from(policy_pipeline)
             policy_pipeline.pipeline.stages.each do |policy_stage|
@@ -57,6 +61,12 @@ def insert_jobs(from_stage:, to_stage:)
               job.assign_attributes(pipeline: pipeline, stage_idx: to_stage.position)
               job.set_execution_policy_job!
               to_stage.statuses << job
+
+              track_internal_event(
+                'execute_job_pipeline_execution_policy',
+                project: project,
+                namespace: namespace
+              )
             end
           end
 
diff --git a/ee/spec/lib/gitlab/ci/pipeline/pipeline_execution_policies/jobs_merger_spec.rb b/ee/spec/lib/gitlab/ci/pipeline/pipeline_execution_policies/jobs_merger_spec.rb
index 5193b7e580f0345d68f3e1112bc20ce89329268d..e36537524af9929fa588a35415f7e37e2d01d5b9 100644
--- a/ee/spec/lib/gitlab/ci/pipeline/pipeline_execution_policies/jobs_merger_spec.rb
+++ b/ee/spec/lib/gitlab/ci/pipeline/pipeline_execution_policies/jobs_merger_spec.rb
@@ -98,6 +98,29 @@
         expect(custom_stage.position).to eq(4)
         expect(custom_stage.statuses.map(&:name)).to contain_exactly('docker')
       end
+
+      it_behaves_like 'internal event tracking' do
+        let(:event) { 'execute_job_pipeline_execution_policy' }
+        let(:category) { described_class.name }
+        let_it_be(:project) { project }
+        let_it_be(:user) { nil }
+        let_it_be(:namespace) { project.group }
+      end
+
+      context 'when the policy has multiple jobs' do
+        let(:pipeline_execution_policies) do
+          build_list(:ci_pipeline_execution_policy, 1,
+            pipeline: build_mock_policy_pipeline({ 'custom' => %w[docker rspec] }))
+        end
+
+        it 'triggers one event per job' do
+          expect { execute }.to trigger_internal_events('execute_job_pipeline_execution_policy')
+                                  .with(category: described_class.name,
+                                    project: project,
+                                    namespace:  project.group)
+                                  .exactly(2).times
+        end
+      end
     end
 
     context 'when custom policy stage is not defined in the main pipeline' do
@@ -110,6 +133,10 @@
 
         expect(pipeline.stages.map(&:name)).to contain_exactly('build', 'test')
       end
+
+      it_behaves_like 'internal event not tracked' do
+        let(:event) { 'execute_job_pipeline_execution_policy' }
+      end
     end
   end
 
@@ -155,5 +182,9 @@
     it 'does not change pipeline stages' do
       expect { execute }.not_to change { pipeline.stages }
     end
+
+    it_behaves_like 'internal event not tracked' do
+      let(:event) { 'execute_job_pipeline_execution_policy' }
+    end
   end
 end