diff --git a/src/material/timepicker/timepicker-toggle.html b/src/material/timepicker/timepicker-toggle.html
index ef15001b8e5a..879329c90dff 100644
--- a/src/material/timepicker/timepicker-toggle.html
+++ b/src/material/timepicker/timepicker-toggle.html
@@ -2,7 +2,8 @@
   mat-icon-button
   type="button"
   aria-haspopup="listbox"
-  [attr.aria-label]="ariaLabel()"
+  [attr.aria-label]="getAriaLabel()"
+  [attr.aria-labelledby]="ariaLabelledby()"
   [attr.aria-expanded]="timepicker().isOpen()"
   [attr.tabindex]="_isDisabled() ? -1 : tabIndex()"
   [disabled]="_isDisabled()"
diff --git a/src/material/timepicker/timepicker-toggle.ts b/src/material/timepicker/timepicker-toggle.ts
index 9bf902390a16..1bf7a67fcdad 100644
--- a/src/material/timepicker/timepicker-toggle.ts
+++ b/src/material/timepicker/timepicker-toggle.ts
@@ -62,6 +62,14 @@ export class MatTimepickerToggle<D> {
     alias: 'aria-label',
   });
 
+  /** Screen-reader labelled by id for the button. */
+  readonly ariaLabelledby = input<string | undefined>(undefined, {
+    alias: 'aria-labelledby',
+  });
+
+  /** Default aria-label for the toggle if none is provided. */
+  private readonly _defaultAriaLabel = 'Open timepicker options';
+
   /** Whether the toggle button is disabled. */
   readonly disabled: InputSignalWithTransform<boolean, unknown> = input(false, {
     transform: booleanAttribute,
@@ -84,4 +92,12 @@ export class MatTimepickerToggle<D> {
       event.stopPropagation();
     }
   }
+
+  /**
+   * Checks for ariaLabelledby and if empty uses custom
+   * aria-label or defaultAriaLabel if neither is provided.
+   */
+  getAriaLabel(): string | null {
+    return this.ariaLabelledby() ? null : this.ariaLabel() || this._defaultAriaLabel;
+  }
 }
diff --git a/tools/public_api_guard/material/timepicker.md b/tools/public_api_guard/material/timepicker.md
index 528d217bd53f..d99141df8ddc 100644
--- a/tools/public_api_guard/material/timepicker.md
+++ b/tools/public_api_guard/material/timepicker.md
@@ -124,15 +124,17 @@ export interface MatTimepickerSelected<D> {
 // @public
 export class MatTimepickerToggle<D> {
     readonly ariaLabel: InputSignal<string | undefined>;
+    readonly ariaLabelledby: InputSignal<string | undefined>;
     readonly disabled: InputSignalWithTransform<boolean, unknown>;
     readonly disableRipple: InputSignalWithTransform<boolean, unknown>;
+    getAriaLabel(): string | null;
     // (undocumented)
     protected _isDisabled: Signal<boolean>;
     protected _open(event: Event): void;
     readonly tabIndex: InputSignal<number | null>;
     readonly timepicker: InputSignal<MatTimepicker<D>>;
     // (undocumented)
-    static ɵcmp: i0.ɵɵComponentDeclaration<MatTimepickerToggle<any>, "mat-timepicker-toggle", ["matTimepickerToggle"], { "timepicker": { "alias": "for"; "required": true; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "disableRipple": { "alias": "disableRipple"; "required": false; "isSignal": true; }; }, {}, never, ["[matTimepickerToggleIcon]"], true, never>;
+    static ɵcmp: i0.ɵɵComponentDeclaration<MatTimepickerToggle<any>, "mat-timepicker-toggle", ["matTimepickerToggle"], { "timepicker": { "alias": "for"; "required": true; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "tabIndex": { "alias": "tabIndex"; "required": false; "isSignal": true; }; "disableRipple": { "alias": "disableRipple"; "required": false; "isSignal": true; }; }, {}, never, ["[matTimepickerToggleIcon]"], true, never>;
     // (undocumented)
     static ɵfac: i0.ɵɵFactoryDeclaration<MatTimepickerToggle<any>, never>;
 }