diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md
index d87ec95912f74cc3b2c52182d664f80168c69f93..8df007979992dad33b493498cc783176cac7da8e 100644
--- a/docs/usage/configuration-options.md
+++ b/docs/usage/configuration-options.md
@@ -2529,6 +2529,11 @@ This works because Renovate will add a "renovate/stability-days" pending status
 
 <!-- markdownlint-enable MD001 -->
 
+## stopUpdatingLabel
+
+On supported platforms it is possible to add a label to a PR to request Renovate stop updating the PR.
+By default this label is `"stop-updating"` however you can configure it to anything you want by changing this `stopUpdatingLabel` field.
+
 ## suppressNotifications
 
 Use this field to suppress various types of warnings and other notifications from Renovate.
diff --git a/lib/config/options/index.ts b/lib/config/options/index.ts
index fb738ad170089c9075a37d1345792da27b7be951..34cceaece77687e617a59297b94a36f95231bb29 100644
--- a/lib/config/options/index.ts
+++ b/lib/config/options/index.ts
@@ -1313,6 +1313,13 @@ const options: RenovateOptions[] = [
     type: 'string',
     default: 'rebase',
   },
+  {
+    name: 'stopUpdatingLabel',
+    description: 'Label to use to request the bot to stop updating a PR.',
+    type: 'string',
+    default: 'stop-updating',
+    supportedPlatforms: ['azure', 'github', 'gitlab', 'gitea'],
+  },
   {
     name: 'stabilityDays',
     description:
diff --git a/lib/config/types.ts b/lib/config/types.ts
index 258b29e3d5a883b5b723e33ede9e6327f37d3518..e102ae643c79161d3c8361675c6dec7987d29c7c 100644
--- a/lib/config/types.ts
+++ b/lib/config/types.ts
@@ -54,6 +54,7 @@ export interface RenovateSharedConfig {
   productLinks?: Record<string, string>;
   prPriority?: number;
   rebaseLabel?: string;
+  stopUpdatingLabel?: string;
   rebaseWhen?: string;
   recreateClosed?: boolean;
   repository?: string;
diff --git a/lib/workers/branch/index.spec.ts b/lib/workers/branch/index.spec.ts
index c7615c389850d900c6ff03da101af57c01801ba4..cfaed31930cce0ff97a219f782501610458fa70a 100644
--- a/lib/workers/branch/index.spec.ts
+++ b/lib/workers/branch/index.spec.ts
@@ -939,6 +939,76 @@ describe('workers/branch/index', () => {
       });
     });
 
+    it('skips branch update if stopUpdatingLabel presents', async () => {
+      getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({
+        updatedPackageFiles: [{}],
+        artifactErrors: [],
+      } as PackageFilesResult);
+      npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({
+        artifactErrors: [],
+        updatedArtifacts: [{}],
+      } as WriteExistingFilesResult);
+      git.branchExists.mockReturnValue(true);
+      platform.getBranchPr.mockResolvedValueOnce({
+        title: 'rebase!',
+        state: PrState.Open,
+        labels: ['stop-updating'],
+        body: `- [ ] <!-- rebase-check -->`,
+      } as Pr);
+      git.isBranchModified.mockResolvedValueOnce(true);
+      schedule.isScheduledNow.mockReturnValueOnce(false);
+      commit.commitFilesToBranch.mockResolvedValueOnce(null);
+      expect(
+        await branchWorker.processBranch({
+          ...config,
+          dependencyDashboardChecks: { 'renovate/some-branch': 'true' },
+          updatedArtifacts: [{ type: 'deletion', path: 'dummy' }],
+        })
+      ).toMatchInlineSnapshot(`
+        Object {
+          "branchExists": true,
+          "prNo": undefined,
+          "result": "no-work",
+        }
+      `);
+      expect(commit.commitFilesToBranch).not.toHaveBeenCalled();
+    });
+
+    it('updates branch if stopUpdatingLabel presents and PR rebase/retry box checked', async () => {
+      getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({
+        updatedPackageFiles: [{}],
+        artifactErrors: [],
+      } as PackageFilesResult);
+      npmPostExtract.getAdditionalFiles.mockResolvedValueOnce({
+        artifactErrors: [],
+        updatedArtifacts: [{}],
+      } as WriteExistingFilesResult);
+      git.branchExists.mockReturnValue(true);
+      platform.getBranchPr.mockResolvedValueOnce({
+        title: 'Update dependency',
+        state: PrState.Open,
+        labels: ['stop-updating'],
+        body: `- [x] <!-- rebase-check -->`,
+      } as Pr);
+      git.isBranchModified.mockResolvedValueOnce(true);
+      schedule.isScheduledNow.mockReturnValueOnce(false);
+      commit.commitFilesToBranch.mockResolvedValueOnce(null);
+      expect(
+        await branchWorker.processBranch({
+          ...config,
+          reuseExistingBranch: false,
+          updatedArtifacts: [{ type: 'deletion', path: 'dummy' }],
+        })
+      ).toMatchInlineSnapshot(`
+        Object {
+          "branchExists": true,
+          "prNo": undefined,
+          "result": "done",
+        }
+      `);
+      expect(commit.commitFilesToBranch).toHaveBeenCalled();
+    });
+
     it('executes post-upgrade tasks if trust is high', async () => {
       const updatedPackageFile: File = {
         type: 'addition',
diff --git a/lib/workers/branch/index.ts b/lib/workers/branch/index.ts
index 11d79a3449b4dbc0872c2177ba0e12d519f31f72..d0d301718824debba2e782d10a8a253b679bc929 100644
--- a/lib/workers/branch/index.ts
+++ b/lib/workers/branch/index.ts
@@ -440,6 +440,26 @@ export async function processBranch(
     }
     const forcedManually = userRebaseRequested || !branchExists;
     config.forceCommit = forcedManually || branchPr?.isConflicted;
+
+    config.stopUpdating = branchPr?.labels?.includes(config.stopUpdatingLabel);
+
+    const prRebaseChecked = branchPr?.body?.includes(
+      `- [x] <!-- rebase-check -->`
+    );
+
+    if (branchExists && dependencyDashboardCheck && config.stopUpdating) {
+      if (!prRebaseChecked) {
+        logger.info(
+          'Branch updating is skipped because stopUpdatingLabel is present in config'
+        );
+        return {
+          branchExists: true,
+          prNo: branchPr?.number,
+          result: BranchResult.NoWork,
+        };
+      }
+    }
+
     const commitSha = await commitFilesToBranch(config);
     // istanbul ignore if
     if (branchPr && platform.refreshPr) {
diff --git a/lib/workers/pr/body/config-description.spec.ts b/lib/workers/pr/body/config-description.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..90d5d94cb4e2c54255575a9335828ab200157194
--- /dev/null
+++ b/lib/workers/pr/body/config-description.spec.ts
@@ -0,0 +1,23 @@
+import { mock } from 'jest-mock-extended';
+import { BranchConfig } from '../../types';
+import { getPrConfigDescription } from './config-description';
+
+jest.mock('../../../util/git');
+
+describe('workers/pr/body/config-description', () => {
+  describe('getPrConfigDescription', () => {
+    let branchConfig: BranchConfig;
+    beforeEach(() => {
+      jest.resetAllMocks();
+      branchConfig = mock<BranchConfig>();
+      branchConfig.branchName = 'branchName';
+    });
+
+    it('handles stopUpdatingLabel correctly', async () => {
+      branchConfig.stopUpdating = true;
+      expect(await getPrConfigDescription(branchConfig)).toContain(
+        `**Rebasing**: Never, or you tick the rebase/retry checkbox.`
+      );
+    });
+  });
+});
diff --git a/lib/workers/pr/body/config-description.ts b/lib/workers/pr/body/config-description.ts
index 17ac4d82d1202a580c4386516e7fb303ca3cefcb..3dc80349749af9dcc573782280f1fba17e49955e 100644
--- a/lib/workers/pr/body/config-description.ts
+++ b/lib/workers/pr/body/config-description.ts
@@ -44,7 +44,7 @@ export async function getPrConfigDescription(
   prBody += emojify(':recycle: **Rebasing**: ');
   if (config.rebaseWhen === 'behind-base-branch') {
     prBody += 'Whenever PR is behind base branch';
-  } else if (config.rebaseWhen === 'never') {
+  } else if (config.rebaseWhen === 'never' || config.stopUpdating) {
     prBody += 'Never';
   } else {
     prBody += 'Whenever PR becomes conflicted';
diff --git a/lib/workers/types.ts b/lib/workers/types.ts
index b007f84e1c46861da4ea6c56d42b39e1b2f805af..d311d0c18a785279f1c791c56dce080225cd9041 100644
--- a/lib/workers/types.ts
+++ b/lib/workers/types.ts
@@ -115,4 +115,5 @@ export interface BranchConfig
   packageFiles?: Record<string, PackageFile[]>;
   prBlockedBy?: PrBlockedBy;
   prNo?: number;
+  stopUpdating?: boolean;
 }