diff --git a/lib/workers/pr/index.spec.ts b/lib/workers/pr/index.spec.ts
index 27520244f7b99e96c6b9b4039aecd528173b6261..1c1a1eb445918cfe72531f9b6de74a1c7e55e624 100644
--- a/lib/workers/pr/index.spec.ts
+++ b/lib/workers/pr/index.spec.ts
@@ -701,4 +701,52 @@ describe('workers/pr/index', () => {
       });
     });
   });
+
+  describe('prepareLabels(config)', () => {
+    it('returns empty array if no labels are configured', () => {
+      const result = prWorker.prepareLabels({});
+      expect(result).toBeArrayOfSize(0);
+    });
+
+    it('only labels', () => {
+      const result = prWorker.prepareLabels({ labels: ['labelA', 'labelB'] });
+      expect(result).toBeArrayOfSize(2);
+      expect(result).toEqual(['labelA', 'labelB']);
+    });
+
+    it('only addLabels', () => {
+      const result = prWorker.prepareLabels({
+        addLabels: ['labelA', 'labelB'],
+      });
+      expect(result).toBeArrayOfSize(2);
+      expect(result).toEqual(['labelA', 'labelB']);
+    });
+
+    it('merge labels and addLabels', () => {
+      const result = prWorker.prepareLabels({
+        labels: ['labelA', 'labelB'],
+        addLabels: ['labelC'],
+      });
+      expect(result).toBeArrayOfSize(3);
+      expect(result).toEqual(['labelA', 'labelB', 'labelC']);
+    });
+
+    it('deduplicate merged labels and addLabels', () => {
+      const result = prWorker.prepareLabels({
+        labels: ['labelA', 'labelB'],
+        addLabels: ['labelB', 'labelC'],
+      });
+      expect(result).toBeArrayOfSize(3);
+      expect(result).toEqual(['labelA', 'labelB', 'labelC']);
+    });
+
+    it('template labels', () => {
+      const result = prWorker.prepareLabels({
+        labels: ['datasource-{{{datasource}}}'],
+        datasource: 'npm',
+      });
+      expect(result).toBeArrayOfSize(1);
+      expect(result).toEqual(['datasource-npm']);
+    });
+  });
 });
diff --git a/lib/workers/pr/index.ts b/lib/workers/pr/index.ts
index 6e9ea8afbd936d0c9f9042bc364c45243a647216..b84edac6aea0a7fa57d21ca74dd6a5fbb6071223 100644
--- a/lib/workers/pr/index.ts
+++ b/lib/workers/pr/index.ts
@@ -53,6 +53,14 @@ function prepareAssigneesReviewers(
   return filterUnavailableUsers(config, normalizedUsernames);
 }
 
+export function prepareLabels(config: RenovateConfig): string[] {
+  const labels = config.labels ?? [];
+  const addLabels = config.addLabels ?? [];
+  return [...new Set([...labels, ...addLabels])].map((label) =>
+    template.compile(label, config)
+  );
+}
+
 export async function addAssigneesReviewers(
   config: RenovateConfig,
   pr: Pr
@@ -430,9 +438,7 @@ export async function ensurePr(
           targetBranch: config.baseBranch,
           prTitle,
           prBody,
-          labels: [...new Set([...config.labels, ...config.addLabels])].map(
-            (label) => template.compile(label, config)
-          ),
+          labels: prepareLabels(config),
           platformOptions: getPlatformPrOptions(config),
           draftPR: config.draftPR,
         });
diff --git a/lib/workers/repository/onboarding/pr/index.spec.ts b/lib/workers/repository/onboarding/pr/index.spec.ts
index debdb38980893bcdb7d9b4e8bebb35cf25037c59..a2beb95758b0f7cc3eb264323defc210cf941c70 100644
--- a/lib/workers/repository/onboarding/pr/index.spec.ts
+++ b/lib/workers/repository/onboarding/pr/index.spec.ts
@@ -45,6 +45,24 @@ describe('workers/repository/onboarding/pr/index', () => {
       expect(platform.createPr).toHaveBeenCalledTimes(1);
       createPrBody = platform.createPr.mock.calls[0][0].prBody;
     });
+
+    it('creates PR with labels', async () => {
+      await ensureOnboardingPr(
+        {
+          ...config,
+          labels: ['label'],
+          addLabels: ['label', 'additional-label'],
+        },
+        packageFiles,
+        branches
+      );
+      expect(platform.createPr).toHaveBeenCalledTimes(1);
+      expect(platform.createPr.mock.calls[0][0].labels).toEqual([
+        'label',
+        'additional-label',
+      ]);
+    });
+
     it('returns if PR does not need updating', async () => {
       platform.getBranchPr.mockResolvedValue(
         partial<Pr>({
diff --git a/lib/workers/repository/onboarding/pr/index.ts b/lib/workers/repository/onboarding/pr/index.ts
index bf0c7be77dd29f67052e695e9b73fb1f6b232cfe..cd8ac079c23263ef8a8d9c08c9f53f780d0f46bd 100644
--- a/lib/workers/repository/onboarding/pr/index.ts
+++ b/lib/workers/repository/onboarding/pr/index.ts
@@ -5,7 +5,11 @@ import type { PackageFile } from '../../../../manager/types';
 import { platform } from '../../../../platform';
 import { emojify } from '../../../../util/emoji';
 import { deleteBranch, isBranchModified } from '../../../../util/git';
-import { addAssigneesReviewers, getPlatformPrOptions } from '../../../pr';
+import {
+  addAssigneesReviewers,
+  getPlatformPrOptions,
+  prepareLabels,
+} from '../../../pr';
 import type { BranchConfig } from '../../../types';
 import { getBaseBranchDesc } from './base-branch';
 import { getConfigDesc } from './config-description';
@@ -127,7 +131,7 @@ If you need any further assistance then you can also [request help here](${confi
     return;
   }
   logger.debug('Creating onboarding PR');
-  const labels: string[] = config.addLabels ?? [];
+  const labels: string[] = prepareLabels(config);
   try {
     if (GlobalConfig.get('dryRun')) {
       logger.info('DRY-RUN: Would create onboarding PR');