diff --git a/docs/src/__examples__/Heading/DEFAULT.tsx b/docs/src/__examples__/Heading/DEFAULT.tsx
index 7475340972..c9c4fb7e0e 100644
--- a/docs/src/__examples__/Heading/DEFAULT.tsx
+++ b/docs/src/__examples__/Heading/DEFAULT.tsx
@@ -2,7 +2,11 @@ import React from "react";
 import { Heading } from "@kiwicom/orbit-components";
 
 export default {
-  Example: () => <Heading>Orbit components</Heading>,
+  Example: () => (
+    <Heading role="heading" level={1}>
+      Orbit components
+    </Heading>
+  ),
   exampleKnobs: [
     {
       component: "Heading",
@@ -26,7 +30,7 @@ export default {
             "title5",
             "title6",
           ],
-          defaultValue: "div",
+          defaultValue: "title1",
         },
       ],
     },
diff --git a/docs/src/documentation/03-components/09-text/heading/03-accessibility.mdx b/docs/src/documentation/03-components/09-text/heading/03-accessibility.mdx
new file mode 100644
index 0000000000..3892c4851d
--- /dev/null
+++ b/docs/src/documentation/03-components/09-text/heading/03-accessibility.mdx
@@ -0,0 +1,68 @@
+---
+title: Accessibility
+redirect_from:
+  - /components/heading/accessibility/
+---
+
+# Accessibility
+
+## Heading
+
+The Heading component has been designed with accessibility in mind.
+
+The component offers flexibility in terms of the HTML element used for the root node, the `role` attribute, and the `level` attribute.
+These properties allow for the creation of semantic and accessible headings.
+
+| Name  | Type                                                    | Description                                                                                                                 |
+| :---- | :------------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------- |
+| as    | `"h1" \| "h2" \| "h3" \| "h4" \| "h5" \| "h6" \| "div"` | Defines the HTML element to be rendered.                                                                                    |
+| role  | `"heading"`                                             | Can only be used if `as="div"`. If defined, sets the role of the element to be "heading".                                   |
+| level | `number`                                                | Can only be used if `as="div"` and "`role="heading`". Defines the `aria-level` of the rendered `div` with the heading role. |
+
+All the props above are optional by default.
+
+If they are not provided, the component will render a `div` element with no role or aria-level defined.
+It is not semantically wrong but won't tell screen readers that the element is a heading. This should be used only for decorative purposes.
+
+```jsx
+<Heading>Hello World!</Heading>
+```
+
+renders:
+
+```html
+<div>Hello World!</div>
+```
+
+If the `as` prop is set to `"div"` (or undefined), the `role` prop is optional, but only accepts one possible value (if not `undefined`): `"heading"`.
+If the `role` prop is set to `"heading"`, the `level` prop must be defined as well. It will tell assistive technologies the level of the heading.
+The `level` prop must be a number between 1 and 6 and cannot be used if the `role` prop is not set to `"heading"`.
+
+```jsx
+<Heading as="div" role="heading" level={1}>
+  Hello World!
+</Heading>
+```
+
+renders:
+
+```html
+<div role="heading" aria-level="1">Hello World!</div>
+```
+
+If the `as` prop is set to `"h1"`, `"h2"`, `"h3"`, `"h4"`, `"h5"`, or `"h6"`, the component will render the corresponding HTML element.
+In that case, the `role` and `level` props are not needed, since assistive technologies will recognize the element as a heading and its correct level automatically.
+
+```jsx
+<Heading as="h1">Hello World!</Heading>
+```
+
+renders:
+
+```html
+<h1>Hello World!</h1>
+```
+
+### Compatibility with SkipNavigation
+
+The `dataA11ySection` prop can be used to link the Heading to a `SkipNavigation` component.
diff --git a/packages/orbit-components/.storybook/orbitDecorator.tsx b/packages/orbit-components/.storybook/orbitDecorator.tsx
index f92323bb25..26439f5a0f 100644
--- a/packages/orbit-components/.storybook/orbitDecorator.tsx
+++ b/packages/orbit-components/.storybook/orbitDecorator.tsx
@@ -45,7 +45,7 @@ const OrbitDecorator: Decorator = (storyFn, context) => {
   return (
     <OrbitProvider useId={React.useId} theme={{ ...defaultTheme }}>
       <div style={{ padding: "20px" }}>
-        <Heading spaceAfter="medium" inverted={inverted}>
+        <Heading as="h1" spaceAfter="medium" inverted={inverted}>
           {context.kind}
         </Heading>
         <Text spaceAfter="largest" type={inverted ? "white" : "primary"}>
diff --git a/packages/orbit-components/cypress/integration/pages/heading-media-query-props.tsx b/packages/orbit-components/cypress/integration/pages/heading-media-query-props.tsx
index 31ca891c86..ee8372bd6b 100644
--- a/packages/orbit-components/cypress/integration/pages/heading-media-query-props.tsx
+++ b/packages/orbit-components/cypress/integration/pages/heading-media-query-props.tsx
@@ -4,6 +4,8 @@ import { Heading } from "@kiwicom/orbit-components";
 export default function HeadingMediaProps() {
   return (
     <Heading
+      role="heading"
+      level={1}
       type="title0"
       mediumMobile={{ type: "display" }}
       largeMobile={{ spaceAfter: "small", type: "title2" }}
diff --git a/packages/orbit-components/cypress/integration/pages/media-queries.tsx b/packages/orbit-components/cypress/integration/pages/media-queries.tsx
index 019cdeed6d..c819ff33b5 100644
--- a/packages/orbit-components/cypress/integration/pages/media-queries.tsx
+++ b/packages/orbit-components/cypress/integration/pages/media-queries.tsx
@@ -5,12 +5,36 @@ export default function MediaQueries() {
   const query = useMediaQuery();
   return (
     <>
-      {query.isMediumMobile && <Heading type="title0">Medium mobile</Heading>}
-      {query.isLargeMobile && <Heading type="title0">Large mobile</Heading>}
-      {query.isTablet && <Heading type="title0">Tablet</Heading>}
-      {query.isDesktop && <Heading type="title0">Desktop</Heading>}
-      {query.isLargeDesktop && <Heading type="title0">Large desktop</Heading>}
-      {query.prefersReducedMotion && <Heading type="title0">Reduced motion</Heading>}
+      {query.isMediumMobile && (
+        <Heading role="heading" level={1} type="title0">
+          Medium mobile
+        </Heading>
+      )}
+      {query.isLargeMobile && (
+        <Heading role="heading" level={1} type="title0">
+          Large mobile
+        </Heading>
+      )}
+      {query.isTablet && (
+        <Heading role="heading" level={1} type="title0">
+          Tablet
+        </Heading>
+      )}
+      {query.isDesktop && (
+        <Heading role="heading" level={1} type="title0">
+          Desktop
+        </Heading>
+      )}
+      {query.isLargeDesktop && (
+        <Heading role="heading" level={1} type="title0">
+          Large desktop
+        </Heading>
+      )}
+      {query.prefersReducedMotion && (
+        <Heading role="heading" level={1} type="title0">
+          Reduced motion
+        </Heading>
+      )}
     </>
   );
 }
diff --git a/packages/orbit-components/src/Card/README.md b/packages/orbit-components/src/Card/README.md
index 8fc1336191..804d4eff57 100644
--- a/packages/orbit-components/src/Card/README.md
+++ b/packages/orbit-components/src/Card/README.md
@@ -18,20 +18,20 @@ After adding import into your project you can use it simply like:
 
 Table below contains all types of the props available in the Card component.
 
-| Name        | Type                         | Default | Description                                                                                                            |
-| :---------- | :--------------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------- |
-| actions     | `React.Node`                 |         | Optional prop for Action components in header of Card                                                                  |
-| children    | `React.Node`                 |         | The content of the Card. You can use only [CardSection](#cardsection)                                                  |
-| dataTest    | `string`                     |         | Optional prop for testing purposes                                                                                     |
-| id          | `string`                     |         | Set `id` for `Card`                                                                                                    |
-| description | `React.Node`                 |         | The description of the Card                                                                                            |
-| header      | `React.Node`                 |         | The header of the Card. Useful when you need a different layout than the combination of e.g. `title` and `description` |
-| loading     | `boolean`                    |         | If `true` `Loading` will be rendered                                                                                   |
-| onClose     | `() => void \| Promise`      |         | Callback that is triggered when Card is closing                                                                        |
-| title       | `React.Node`                 |         | The title of the Card                                                                                                  |
-| titleAs     | [`enum`](#enum)              | `"h2"`  | The element used for the root node of the title of Card.                                                               |
-| margin      | `string \| number \| Object` |         | Utility prop to set margin.                                                                                            |
-| labelClose  | `string`                     | `Close` | Property for passing translation string to close Button.                                                               |
+| Name        | Type                         | Default | Description                                                                                                             |
+| :---------- | :--------------------------- | :------ | :---------------------------------------------------------------------------------------------------------------------- |
+| actions     | `React.Node`                 |         | Optional prop for Action components in header of Card.                                                                  |
+| children    | `React.Node`                 |         | The content of the Card. You can use only [CardSection](#cardsection).                                                  |
+| dataTest    | `string`                     |         | Optional prop for testing purposes.                                                                                     |
+| id          | `string`                     |         | Set `id` for `Card`.                                                                                                    |
+| description | `React.Node`                 |         | The description of the Card.                                                                                            |
+| header      | `React.Node`                 |         | The header of the Card. Useful when you need a different layout than the combination of e.g. `title` and `description`. |
+| loading     | `boolean`                    |         | If `true`, a loading animation will be rendered.                                                                        |
+| onClose     | `() => void \| Promise`      |         | Callback that is triggered when Card is closing.                                                                        |
+| title       | `React.Node`                 |         | The title of the Card.                                                                                                  |
+| titleAs     | [`enum`](#enum)              | `"h2"`  | The element used for the root node of the title of Card. It **does not** impact the visual style of the title.          |
+| margin      | `string \| number \| Object` |         | Utility prop to set margin.                                                                                             |
+| labelClose  | `string`                     | `Close` | Property for passing translation string to close Button.                                                                |
 
 ### CardSection
 
diff --git a/packages/orbit-components/src/Card/components/Header.tsx b/packages/orbit-components/src/Card/components/Header.tsx
index 1a816544af..58e299d25f 100644
--- a/packages/orbit-components/src/Card/components/Header.tsx
+++ b/packages/orbit-components/src/Card/components/Header.tsx
@@ -51,6 +51,7 @@ const Header = ({
             <Heading
               type={isSection ? "title4" : "title3"}
               as={titleAs}
+              role={undefined} // To avoid requiring the `level` prop
               dataA11ySection={dataA11ySection}
             >
               {title}
diff --git a/packages/orbit-components/src/Heading/README.md b/packages/orbit-components/src/Heading/README.md
index f3fd5d843f..769feb92a5 100644
--- a/packages/orbit-components/src/Heading/README.md
+++ b/packages/orbit-components/src/Heading/README.md
@@ -16,22 +16,24 @@ After adding import to your project you can use it simply like:
 
 The table below contains all types of props available in the Heading component.
 
-| Name            | Type                       | Default    | Description                                                                                         |
-| :-------------- | :------------------------- | :--------- | :-------------------------------------------------------------------------------------------------- |
-| as              | [`enum`](#enum)            | `"div"`    | The element used for the root node.                                                                 |
-| children        | `React.Node`               |            | The content of the Heading.                                                                         |
-| dataTest        | `string`                   |            | Optional prop for testing purposes.                                                                 |
-| align           | [`enum`](#enum)            | `left`     | `text-align` of `Heading` component                                                                 |
-| dataA11ySection | `string`                   |            | ID for a `<SkipNavigation>` component.                                                              |
-| id              | `string`                   |            | Adds `id` HTML attribute to an element. Expects a unique ID.                                        |
-| inverted        | `boolean`                  |            | The `true`, the Heading color will be white.                                                        |
-| spaceAfter      | `enum`                     |            | Additional `margin-bottom` after component.                                                         |
-| **type**        | [`enum`](#enum)            | `"title1"` | The size type of Heading.                                                                           |
-| mediumMobile    | [`Object`](#media-queries) |            | Object for setting up properties for the mediumMobile viewport. [See Media queries](#media-queries) |
-| largeMobile     | [`Object`](#media-queries) |            | Object for setting up properties for the largeMobile viewport. [See Media queries](#media-queries)  |
-| tablet          | [`Object`](#media-queries) |            | Object for setting up properties for the tablet viewport. [See Media queries](#media-queries)       |
-| desktop         | [`Object`](#media-queries) |            | Object for setting up properties for the desktop viewport. [See Media queries](#media-queries)      |
-| largeDesktop    | [`Object`](#media-queries) |            | Object for setting up properties for the largeDesktop viewport. [See Media queries](#media-queries) |
+| Name            | Type                       | Default    | Description                                                                                                |
+| :-------------- | :------------------------- | :--------- | :--------------------------------------------------------------------------------------------------------- |
+| as              | [`enum`](#enum)            | `"div"`    | The element used for the root node.                                                                        |
+| role            | `"heading"`                |            | The role attribute of the element. Can only be defined if `as="div"`. If defined, `level` must be defined. |
+| level           | `number`                   |            | The level of the Heading. Required if `role` is defined as `"heading"`.                                    |
+| children        | `React.Node`               |            | The content of the Heading.                                                                                |
+| dataTest        | `string`                   |            | Optional prop for testing purposes.                                                                        |
+| align           | [`enum`](#enum)            | `left`     | `text-align` of `Heading` component.                                                                       |
+| dataA11ySection | `string`                   |            | ID for a `<SkipNavigation>` component.                                                                     |
+| id              | `string`                   |            | Adds `id` HTML attribute to an element. Expects a unique ID.                                               |
+| inverted        | `boolean`                  |            | The `true`, the Heading color will be white.                                                               |
+| spaceAfter      | `enum`                     |            | Additional `margin-bottom` after component.                                                                |
+| **type**        | [`enum`](#enum)            | `"title1"` | The size type of Heading.                                                                                  |
+| mediumMobile    | [`Object`](#media-queries) |            | Object for setting up properties for the mediumMobile viewport. [See Media queries](#media-queries)        |
+| largeMobile     | [`Object`](#media-queries) |            | Object for setting up properties for the largeMobile viewport. [See Media queries](#media-queries)         |
+| tablet          | [`Object`](#media-queries) |            | Object for setting up properties for the tablet viewport. [See Media queries](#media-queries)              |
+| desktop         | [`Object`](#media-queries) |            | Object for setting up properties for the desktop viewport. [See Media queries](#media-queries)             |
+| largeDesktop    | [`Object`](#media-queries) |            | Object for setting up properties for the largeDesktop viewport. [See Media queries](#media-queries)        |
 
 ### enum
 
diff --git a/packages/orbit-components/src/Heading/__tests__/index.test.tsx b/packages/orbit-components/src/Heading/__tests__/index.test.tsx
index 8bce02b824..a754a75559 100644
--- a/packages/orbit-components/src/Heading/__tests__/index.test.tsx
+++ b/packages/orbit-components/src/Heading/__tests__/index.test.tsx
@@ -18,6 +18,15 @@ describe("Heading", () => {
     expect(heading).toHaveAttribute("id", "id");
   });
 
+  it("renders correct aria-level", () => {
+    render(
+      <Heading role="heading" level={2}>
+        Title
+      </Heading>,
+    );
+    expect(screen.getByRole("heading")).toHaveAttribute("aria-level", "2");
+  });
+
   it.each(Object.values(ALIGN))("should have expected styles from align %s", align => {
     render(
       <Heading dataTest={align} align={align}>
diff --git a/packages/orbit-components/src/Heading/index.tsx b/packages/orbit-components/src/Heading/index.tsx
index 36a423ed08..e44f36b9d9 100644
--- a/packages/orbit-components/src/Heading/index.tsx
+++ b/packages/orbit-components/src/Heading/index.tsx
@@ -15,6 +15,8 @@ const Heading = ({
   type = TYPE_OPTIONS.TITLE0,
   align = ALIGN.START,
   as: Component = ELEMENT_OPTIONS.DIV,
+  level,
+  role,
   dataTest,
   inverted = false,
   spaceAfter,
@@ -44,9 +46,10 @@ const Heading = ({
 
   return (
     <Component
+      aria-level={Component === "div" ? level : undefined}
       id={id}
       data-test={dataTest}
-      role={Component === "div" ? "heading" : undefined}
+      role={Component === "div" ? role : undefined}
       data-a11y-section={dataA11ySection}
       className={cx(
         "orbit-heading font-base m-0",
diff --git a/packages/orbit-components/src/Heading/types.d.ts b/packages/orbit-components/src/Heading/types.d.ts
index 5663e8bf80..01a3d9e525 100644
--- a/packages/orbit-components/src/Heading/types.d.ts
+++ b/packages/orbit-components/src/Heading/types.d.ts
@@ -20,13 +20,28 @@ export type As = "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "div";
 
 type Align = "start" | "center" | "end" | "justify";
 
+type LevelProps =
+  | {
+      as: Exclude<As, "div">;
+      role?: never;
+      level?: never;
+    }
+  | {
+      as?: "div";
+      role: "heading";
+      level: number;
+    }
+  | {
+      as?: "div";
+      role?: undefined;
+      level?: never;
+    };
+
 interface MediaQuery extends Common.SpaceAfter {
   readonly type?: Type;
   readonly align?: Align;
 }
-
-export interface Props extends Common.Globals, Common.SpaceAfter {
-  readonly as?: As;
+export interface BaseProps extends Common.Globals, Common.SpaceAfter {
   readonly type?: Type;
   readonly align?: Align;
   readonly children: React.ReactNode;
@@ -39,3 +54,5 @@ export interface Props extends Common.Globals, Common.SpaceAfter {
   readonly desktop?: MediaQuery;
   readonly largeDesktop?: MediaQuery;
 }
+
+export type Props = BaseProps & LevelProps;