diff --git a/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue b/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue
index e7a1b0583418d44713aedaa238927739755f5dde..11ac024b799b744a9d4d26815540d5cddbb54ad0 100644
--- a/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue
+++ b/app/assets/javascripts/content_editor/components/wrappers/table_cell_base.vue
@@ -7,7 +7,7 @@ import { __, n__ } from '~/locale';
 const TABLE_CELL_HEADER = 'th';
 const TABLE_CELL_BODY = 'td';
 
-function getDropdownItems({ selectedRect, cellType, rowspan = 1, colspan = 1 }) {
+function getDropdownItems({ selectedRect, cellType, rowspan = 1, colspan = 1, align = 'left' }) {
   const totalRows = selectedRect?.map.height;
   const totalCols = selectedRect?.map.width;
   const isTableBodyCell = cellType === TABLE_CELL_BODY;
@@ -20,7 +20,19 @@ function getDropdownItems({ selectedRect, cellType, rowspan = 1, colspan = 1 })
   const showDeleteRowOption = totalRows > selectedRows + 1 && isTableBodyCell;
   const showDeleteColumnOption = totalCols > selectedCols;
 
+  const isTableBodyHeader = cellType === TABLE_CELL_HEADER;
+  const showAlignLeftOption = isTableBodyHeader && (align === 'center' || align === 'right');
+  const showAlignCenterOption = isTableBodyHeader && align !== 'center';
+  const showAlignRightOption = isTableBodyHeader && align !== 'right';
+
   return [
+    {
+      items: [
+        showAlignLeftOption && { text: __('Align column left'), value: 'alignColumnLeft' },
+        showAlignCenterOption && { text: __('Align column center'), value: 'alignColumnCenter' },
+        showAlignRightOption && { text: __('Align column right'), value: 'alignColumnRight' },
+      ].filter(Boolean),
+    },
     {
       items: [
         { text: __('Insert column before'), value: 'addColumnBefore' },
@@ -93,6 +105,7 @@ export default {
         cellType: this.cellType,
         rowspan: this.node.attrs.rowspan,
         colspan: this.node.attrs.colspan,
+        align: this.node.attrs.align,
       });
     },
   },
@@ -129,7 +142,7 @@ export default {
 
     runCommand({ value: command }) {
       this.hideDropdown();
-      this.editor.chain()[command]().run();
+      this.editor.chain()[command](this.getPos()).run();
     },
 
     hideDropdown() {
@@ -143,6 +156,7 @@ export default {
     :as="cellType"
     :rowspan="node.attrs.rowspan || 1"
     :colspan="node.attrs.colspan || 1"
+    :align="node.attrs.align || 'left'"
     dir="auto"
     class="gl-m-0! gl-p-0! gl-relative"
     @click="hideDropdown"
@@ -168,6 +182,10 @@ export default {
         @action="runCommand"
       />
     </span>
-    <node-view-content as="div" class="gl-p-5 gl-min-w-10" />
+    <node-view-content
+      as="div"
+      class="gl-p-5 gl-min-w-10"
+      :style="{ 'text-align': node.attrs.align || 'left' }"
+    />
   </node-view-wrapper>
 </template>
diff --git a/app/assets/javascripts/content_editor/extensions/table_cell.js b/app/assets/javascripts/content_editor/extensions/table_cell.js
index 9f437ce066cf9acdc2758b7b1ab7aaab107493b9..53dba4fd960d7b2a8d080bbf7707981b9a8998ea 100644
--- a/app/assets/javascripts/content_editor/extensions/table_cell.js
+++ b/app/assets/javascripts/content_editor/extensions/table_cell.js
@@ -5,6 +5,17 @@ import TableCellBodyWrapper from '../components/wrappers/table_cell_body.vue';
 export default TableCell.extend({
   content: 'block+',
 
+  addAttributes() {
+    return {
+      ...this.parent?.(),
+      align: {
+        default: 'left',
+        parseHTML: (element) => element.getAttribute('align') || element.style.textAlign || 'left',
+        renderHTML: () => '',
+      },
+    };
+  },
+
   addNodeView() {
     return VueNodeViewRenderer(TableCellBodyWrapper);
   },
diff --git a/app/assets/javascripts/content_editor/extensions/table_header.js b/app/assets/javascripts/content_editor/extensions/table_header.js
index 045fd03199bea8d45ab22308152e09a2ddb478f0..ca2a0eb5cfda5d5889f8b9cdb614f6feaaef323a 100644
--- a/app/assets/javascripts/content_editor/extensions/table_header.js
+++ b/app/assets/javascripts/content_editor/extensions/table_header.js
@@ -1,9 +1,45 @@
 import { TableHeader } from '@tiptap/extension-table-header';
 import { VueNodeViewRenderer } from '@tiptap/vue-2';
+import { CellSelection } from '@tiptap/pm/tables';
 import TableCellHeaderWrapper from '../components/wrappers/table_cell_header.vue';
 
 export default TableHeader.extend({
   content: 'block+',
+
+  addAttributes() {
+    return {
+      ...this.parent?.(),
+      align: {
+        default: 'left',
+        parseHTML: (element) => element.getAttribute('align') || element.style.textAlign || 'left',
+        renderHTML: () => '',
+      },
+    };
+  },
+
+  addCommands() {
+    return {
+      ...this.parent?.(),
+      alignColumn: (pos, align) => ({ commands }) => {
+        commands.selectColumn(pos);
+        commands.updateAttributes('tableHeader', { align });
+        commands.updateAttributes('tableCell', { align });
+      },
+      alignColumnLeft: (pos) => ({ commands }) => commands.alignColumn(pos, 'left'),
+      alignColumnCenter: (pos) => ({ commands }) => commands.alignColumn(pos, 'center'),
+      alignColumnRight: (pos) => ({ commands }) => commands.alignColumn(pos, 'right'),
+      selectColumn: (pos) => ({ tr, dispatch }) => {
+        if (dispatch) {
+          const position = tr.doc.resolve(pos);
+          const colSelection = CellSelection.colSelection(position);
+          tr.setSelection(colSelection);
+        }
+
+        return true;
+      },
+    };
+  },
+
   addNodeView() {
     return VueNodeViewRenderer(TableCellHeaderWrapper);
   },
diff --git a/app/assets/javascripts/content_editor/services/serialization_helpers.js b/app/assets/javascripts/content_editor/services/serialization_helpers.js
index 87959a44560f5e493fceac3d4e231d97d160318b..2734879e4c4263d6d9803d119f210f28246d12ab 100644
--- a/app/assets/javascripts/content_editor/services/serialization_helpers.js
+++ b/app/assets/javascripts/content_editor/services/serialization_helpers.js
@@ -2,8 +2,8 @@ import { uniq, isString, omit, isFunction } from 'lodash';
 import { removeLastSlashInUrlPath, removeUrlProtocol } from '../../lib/utils/url_utility';
 
 const defaultAttrs = {
-  td: { colspan: 1, rowspan: 1, colwidth: null },
-  th: { colspan: 1, rowspan: 1, colwidth: null },
+  td: { colspan: 1, rowspan: 1, colwidth: null, align: 'left' },
+  th: { colspan: 1, rowspan: 1, colwidth: null, align: 'left' },
 };
 
 const defaultIgnoreAttrs = ['sourceMarkdown', 'sourceMapKey'];
diff --git a/app/assets/stylesheets/components/content_editor.scss b/app/assets/stylesheets/components/content_editor.scss
index 97f2add4e7771947259d1b2b2d9673d63f84ac4a..c46eb12f4c714f8ea30f90847efef3e0890c4085 100644
--- a/app/assets/stylesheets/components/content_editor.scss
+++ b/app/assets/stylesheets/components/content_editor.scss
@@ -35,6 +35,10 @@
     background-color: transparent;
   }
 
+  th[align] *, td[align] * {
+    text-align: inherit;
+  }
+
   td,
   th,
   li,
diff --git a/glfm_specification/output_example_snapshots/prosemirror_json.yml b/glfm_specification/output_example_snapshots/prosemirror_json.yml
index 95e7003a202affa32d91e17a734bf228f8b55649..bec8624ebe7ab7d51f1a437120251fc68db0dfa6 100644
--- a/glfm_specification/output_example_snapshots/prosemirror_json.yml
+++ b/glfm_specification/output_example_snapshots/prosemirror_json.yml
@@ -2947,7 +2947,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -3011,7 +3012,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -3229,7 +3231,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -3881,7 +3884,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5244,7 +5248,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5263,7 +5268,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5287,7 +5293,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5306,7 +5313,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5344,7 +5352,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5363,7 +5372,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5387,7 +5397,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5406,7 +5417,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5444,7 +5456,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5468,7 +5481,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5505,7 +5519,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5556,7 +5571,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5575,7 +5591,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5599,7 +5616,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5618,7 +5636,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5673,7 +5692,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5692,7 +5712,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5716,7 +5737,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5735,7 +5757,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5759,7 +5782,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5778,7 +5802,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5834,7 +5859,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5853,7 +5879,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5877,7 +5904,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5896,7 +5924,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5914,7 +5943,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5933,7 +5963,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5971,7 +6002,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -5990,7 +6022,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -23111,7 +23144,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -23130,7 +23164,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -23154,7 +23189,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -23178,7 +23214,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -23211,7 +23248,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -23235,7 +23273,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -23775,7 +23814,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -23794,7 +23834,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -23818,7 +23859,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
@@ -23865,7 +23907,8 @@
                 "attrs": {
                   "colspan": 1,
                   "rowspan": 1,
-                  "colwidth": null
+                  "colwidth": null,
+                  "align": "left"
                 },
                 "content": [
                   {
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 28cfe4f90a6a1448c0cf18c4af2c8b21fb652845..56834765d76093636f9d231243b62e2bc5a9d836 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -4803,6 +4803,15 @@ msgstr ""
 msgid "Algorithm"
 msgstr ""
 
+msgid "Align column center"
+msgstr ""
+
+msgid "Align column left"
+msgstr ""
+
+msgid "Align column right"
+msgstr ""
+
 msgid "All"
 msgstr ""
 
diff --git a/spec/frontend/content_editor/components/wrappers/table_cell_base_spec.js b/spec/frontend/content_editor/components/wrappers/table_cell_base_spec.js
index 94628f2b2c581cd8290c4b5661d391d10034e953..9f233f2f4121b5e976c2d95a01d193198c3c24f1 100644
--- a/spec/frontend/content_editor/components/wrappers/table_cell_base_spec.js
+++ b/spec/frontend/content_editor/components/wrappers/table_cell_base_spec.js
@@ -149,6 +149,10 @@ describe('content/components/wrappers/table_cell_base', () => {
       },
     );
 
+    it('does not show alignment options for table cells', () => {
+      expect(findDropdown().text()).not.toContain('Align');
+    });
+
     describe("when current row is the table's header", () => {
       beforeEach(async () => {
         // Remove 2 rows condition
@@ -179,6 +183,44 @@ describe('content/components/wrappers/table_cell_base', () => {
       });
     });
 
+    describe.each`
+      currentAlignment | visibleOptions         | newAlignment | command
+      ${'left'}        | ${['center', 'right']} | ${'center'}  | ${'alignColumnCenter'}
+      ${'center'}      | ${['left', 'right']}   | ${'right'}   | ${'alignColumnRight'}
+      ${'right'}       | ${['left', 'center']}  | ${'left'}    | ${'alignColumnLeft'}
+    `(
+      'when align=$currentAlignment',
+      ({ currentAlignment, visibleOptions, newAlignment, command }) => {
+        beforeEach(async () => {
+          Object.assign(node.attrs, { align: currentAlignment });
+
+          createWrapper({ cellType: 'th' });
+
+          await nextTick();
+        });
+
+        visibleOptions.forEach((alignment) => {
+          it(`shows "Align column ${alignment}" option`, () => {
+            expect(findDropdown().text()).toContain(`Align column ${alignment}`);
+          });
+        });
+
+        it(`does not show "Align column ${currentAlignment}" option`, () => {
+          expect(findDropdown().text()).not.toContain(`Align column ${currentAlignment}`);
+        });
+
+        it('allows changing alignment', async () => {
+          const mocks = mockChainedCommands(editor, [command, 'run']);
+
+          await wrapper
+            .findByRole('button', { name: `Align column ${newAlignment}` })
+            .trigger('click');
+
+          expect(mocks[command]).toHaveBeenCalled();
+        });
+      },
+    );
+
     describe.each`
       attrs             | rect
       ${{ rowspan: 2 }} | ${{ top: 0, left: 0, bottom: 2, right: 1 }}
diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js
index c329a12bcc4aff008ed0e638f57920c468ab60fc..16f8fc23ce7a9f58d0346872bc070d72dc207590 100644
--- a/spec/frontend/content_editor/services/markdown_serializer_spec.js
+++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js
@@ -1080,6 +1080,38 @@ _An elephant at sunset_
     );
   });
 
+  it('correctly serializes a table with inline content with alignment', () => {
+    expect(
+      serialize(
+        table(
+          // each table cell must contain at least one paragraph
+          tableRow(
+            tableHeader({ align: 'center' }, paragraph('header')),
+            tableHeader({ align: 'right' }, paragraph('header')),
+            tableHeader({ align: 'left' }, paragraph('header')),
+          ),
+          tableRow(
+            tableCell(paragraph('cell')),
+            tableCell(paragraph('cell')),
+            tableCell(paragraph('cell')),
+          ),
+          tableRow(
+            tableCell(paragraph('cell')),
+            tableCell(paragraph('cell')),
+            tableCell(paragraph('cell')),
+          ),
+        ),
+      ).trim(),
+    ).toBe(
+      `
+| header | header | header |
+|:------:|-------:|--------|
+| cell | cell | cell |
+| cell | cell | cell |
+    `.trim(),
+    );
+  });
+
   it('correctly serializes a table with a pipe in a cell', () => {
     expect(
       serialize(