diff --git a/lib/modules/manager/gradle/parser.spec.ts b/lib/modules/manager/gradle/parser.spec.ts
index dfc1945fb37598714fc02af4bba3d16ec79c048a..4734a6cbca7e0c59495f50cb8979f550deb9400d 100644
--- a/lib/modules/manager/gradle/parser.spec.ts
+++ b/lib/modules/manager/gradle/parser.spec.ts
@@ -2,7 +2,7 @@ import { codeBlock } from 'common-tags';
 import { Fixtures } from '../../../../test/fixtures';
 import { fs, logger } from '../../../../test/util';
 import { parseGradle, parseProps } from './parser';
-import { REGISTRY_URLS } from './parser/common';
+import { GRADLE_PLUGINS, REGISTRY_URLS } from './parser/common';
 
 jest.mock('../../../util/fs');
 
@@ -788,4 +788,29 @@ describe('modules/manager/gradle/parser', () => {
       expect(vars).toBeEmpty();
     });
   });
+
+  describe('implicit gradle plugins', () => {
+    test.each`
+      def                | input                                           | output
+      ${'baz = "1.2.3"'} | ${'checkstyle { toolVersion = "${baz}" }'}      | ${{ depName: 'checkstyle', packageName: GRADLE_PLUGINS['checkstyle'], currentValue: '1.2.3' }}
+      ${''}              | ${'codenarc { toolVersion = "1.2.3" }'}         | ${{ depName: 'codenarc', packageName: GRADLE_PLUGINS['codenarc'], currentValue: '1.2.3' }}
+      ${''}              | ${'detekt { toolVersion = "1.2.3" }'}           | ${{ depName: 'detekt', packageName: GRADLE_PLUGINS['detekt'], currentValue: '1.2.3' }}
+      ${''}              | ${'findbugs { toolVersion = "1.2.3" }'}         | ${{ depName: 'findbugs', packageName: GRADLE_PLUGINS['findbugs'], currentValue: '1.2.3' }}
+      ${''}              | ${'googleJavaFormat { toolVersion = "1.2.3" }'} | ${{ depName: 'googleJavaFormat', packageName: GRADLE_PLUGINS['googleJavaFormat'], currentValue: '1.2.3' }}
+      ${'baz = "1.2.3"'} | ${'jacoco { toolVersion = baz }'}               | ${{ depName: 'jacoco', packageName: GRADLE_PLUGINS['jacoco'], currentValue: '1.2.3' }}
+      ${'baz = "1.2.3"'} | ${'jacoco { toolVersion = property("baz") }'}   | ${{ depName: 'jacoco', packageName: GRADLE_PLUGINS['jacoco'], currentValue: '1.2.3' }}
+      ${''}              | ${'lombok { version = "1.2.3" }'}               | ${{ depName: 'lombok', packageName: GRADLE_PLUGINS['lombok'], currentValue: '1.2.3' }}
+      ${''}              | ${'pmd { toolVersion = "1.2.3" }'}              | ${{ depName: 'pmd', packageName: GRADLE_PLUGINS['pmd'], currentValue: '1.2.3' }}
+      ${''}              | ${'pmd { foo = "bar"; toolVersion = "1.2.3" }'} | ${{ depName: 'pmd', packageName: GRADLE_PLUGINS['pmd'], currentValue: '1.2.3' }}
+      ${''}              | ${'spotbugs { toolVersion = "1.2.3" }'}         | ${{ depName: 'spotbugs', packageName: GRADLE_PLUGINS['spotbugs'], currentValue: '1.2.3' }}
+      ${''}              | ${'pmd { toolVersion = "@@@" }'}                | ${null}
+      ${''}              | ${'pmd { toolVersion = "${baz}" }'}             | ${null}
+      ${'baz = "1.2.3"'} | ${'pmd { toolVersion = "${baz}.456" }'}         | ${{ depName: 'pmd', currentValue: '1.2.3.456', skipReason: 'unknown-version' }}
+      ${''}              | ${'pmd { [toolVersion = "6.36.0"] }'}           | ${null}
+      ${''}              | ${'unknown { toolVersion = "1.2.3" }'}          | ${null}
+    `('$def | $input', ({ def, input, output }) => {
+      const { deps } = parseGradle([def, input].join('\n'));
+      expect(deps).toMatchObject([output].filter(Boolean));
+    });
+  });
 });
diff --git a/lib/modules/manager/gradle/parser.ts b/lib/modules/manager/gradle/parser.ts
index 53c843eff9f17f04e7bf0f3258913cf7fae7438d..cafbbb3b33e636289b8c2d7c0741677b11fdce0c 100644
--- a/lib/modules/manager/gradle/parser.ts
+++ b/lib/modules/manager/gradle/parser.ts
@@ -2,6 +2,7 @@ import { lang, lexer, query as q } from 'good-enough-parser';
 import { newlineRegex, regEx } from '../../../util/regex';
 import type { PackageDependency } from '../types';
 import {
+  GRADLE_PLUGINS,
   REGISTRY_URLS,
   cleanupTempVars,
   coalesceVariable,
@@ -15,6 +16,7 @@ import {
   handleCustomRegistryUrl,
   handleDepInterpolation,
   handleDepSimpleString,
+  handleImplicitGradlePlugin,
   handleKotlinShortNotationDep,
   handleLibraryDep,
   handleLongFormDep,
@@ -736,6 +738,29 @@ const qApplyFrom = q
   .handler(handleApplyFrom)
   .handler(cleanupTempVars);
 
+// pmd { toolVersion = "1.2.3" }
+const qImplicitGradlePlugin = q
+  .sym(regEx(`^(?:${Object.keys(GRADLE_PLUGINS).join('|')})$`), storeVarToken)
+  .handler((ctx) => storeInTokenMap(ctx, 'pluginName'))
+  .tree({
+    type: 'wrapped-tree',
+    maxDepth: 1,
+    maxMatches: 1,
+    startsWith: '{',
+    endsWith: '}',
+    search: q
+      .sym<Ctx>(regEx(/^(?:toolVersion|version)$/))
+      .op('=')
+      .alt(
+        qTemplateString,
+        qPropertyAccessIdentifier,
+        qVariableAccessIdentifier
+      ),
+  })
+  .handler((ctx) => storeInTokenMap(ctx, 'version'))
+  .handler(handleImplicitGradlePlugin)
+  .handler(cleanupTempVars);
+
 export function parseGradle(
   input: string,
   initVars: PackageVariables = {},
@@ -766,7 +791,8 @@ export function parseGradle(
       qRegistryUrls,
       qVersionCatalogs,
       qLongFormDep,
-      qApplyFrom
+      qApplyFrom,
+      qImplicitGradlePlugin
     ),
   });
 
diff --git a/lib/modules/manager/gradle/parser/common.ts b/lib/modules/manager/gradle/parser/common.ts
index 5bcc454a98564987ac440fafe60ed3e745ba84fd..9b6903361bdfa03e6bf1b7612b36c5aee6b999eb 100644
--- a/lib/modules/manager/gradle/parser/common.ts
+++ b/lib/modules/manager/gradle/parser/common.ts
@@ -8,6 +8,18 @@ export const REGISTRY_URLS = {
   mavenCentral: 'https://repo.maven.apache.org/maven2',
 };
 
+export const GRADLE_PLUGINS = {
+  checkstyle: 'com.puppycrawl.tools:checkstyle',
+  codenarc: 'org.codenarc:CodeNarc',
+  detekt: 'io.gitlab.arturbosch.detekt:detekt-core',
+  findbugs: 'com.google.code.findbugs:findbugs',
+  googleJavaFormat: 'com.google.googlejavaformat:google-java-format',
+  jacoco: 'org.jacoco:jacoco',
+  lombok: 'org.projectlombok:lombok',
+  pmd: 'net.sourceforge.pmd:pmd-java',
+  spotbugs: 'com.github.spotbugs:spotbugs',
+};
+
 export const ANNOYING_METHODS: ReadonlySet<string> = new Set([
   'createXmlValueRemover',
   'events',
diff --git a/lib/modules/manager/gradle/parser/handlers.ts b/lib/modules/manager/gradle/parser/handlers.ts
index 5a26a031e6c1fd723582c0aaf6e77d7550a643ca..c79315c9aef001982178abdd98f1039264fbe125 100644
--- a/lib/modules/manager/gradle/parser/handlers.ts
+++ b/lib/modules/manager/gradle/parser/handlers.ts
@@ -9,6 +9,7 @@ import type { Ctx, GradleManagerData, VariableData } from '../types';
 import { parseDependencyString } from '../utils';
 import {
   ANNOYING_METHODS,
+  GRADLE_PLUGINS,
   REGISTRY_URLS,
   interpolateString,
   loadFromTokenMap,
@@ -374,3 +375,44 @@ export function handleApplyFrom(ctx: Ctx): Ctx {
 
   return ctx;
 }
+
+export function handleImplicitGradlePlugin(ctx: Ctx): Ctx {
+  const pluginName = loadFromTokenMap(ctx, 'pluginName')[0].value;
+  const versionTokens = loadFromTokenMap(ctx, 'version');
+  const versionValue = interpolateString(versionTokens, ctx.globalVars);
+  if (!versionValue) {
+    return ctx;
+  }
+
+  const groupIdArtifactId =
+    GRADLE_PLUGINS[pluginName as keyof typeof GRADLE_PLUGINS];
+  const dep = parseDependencyString(`${groupIdArtifactId}:${versionValue}`);
+  if (!dep) {
+    return ctx;
+  }
+
+  dep.depName = pluginName;
+  dep.packageName = groupIdArtifactId;
+  dep.managerData = {
+    fileReplacePosition: versionTokens[0].offset,
+    packageFile: ctx.packageFile,
+  };
+
+  if (versionTokens.length > 1) {
+    // = template string with multiple variables
+    dep.skipReason = 'unknown-version';
+  } else if (versionTokens[0].type === 'symbol') {
+    const varData = ctx.globalVars[versionTokens[0].value];
+    if (varData) {
+      dep.currentValue = varData.value;
+      dep.managerData = {
+        fileReplacePosition: varData.fileReplacePosition,
+        packageFile: varData.packageFile,
+      };
+    }
+  }
+
+  ctx.deps.push(dep);
+
+  return ctx;
+}