diff --git a/core/misc/cspell/dictionary.txt b/core/misc/cspell/dictionary.txt
index 9650ea786b8d9c7b1f7d37ff0996e5ee94e65bad..c44570872dbcea7c1b7bf5de094d15fbc6154194 100644
--- a/core/misc/cspell/dictionary.txt
+++ b/core/misc/cspell/dictionary.txt
@@ -1086,6 +1086,7 @@ spacebar
 spagna
 specialchars
 spiffiness
+splitbutton
 splitbuttons
 spreadsheetml
 sqlpassword
diff --git a/core/modules/ckeditor5/ckeditor5.ckeditor5.yml b/core/modules/ckeditor5/ckeditor5.ckeditor5.yml
index 0a19bdca9087752f2bf7bca99dbb180d0027a1e2..80e76c686c47863f594f35bad2f5037a389a33f2 100644
--- a/core/modules/ckeditor5/ckeditor5.ckeditor5.yml
+++ b/core/modules/ckeditor5/ckeditor5.ckeditor5.yml
@@ -263,6 +263,7 @@ ckeditor5_codeBlock:
     label: Code Block
     library: ckeditor5/internal.drupal.ckeditor5.codeBlock
     admin_library: ckeditor5/internal.admin.codeBlock
+    class: Drupal\ckeditor5\Plugin\CKEditor5Plugin\CodeBlock
     toolbar_items:
       codeBlock:
         label: Code Block
diff --git a/core/modules/ckeditor5/ckeditor5.module b/core/modules/ckeditor5/ckeditor5.module
index cf7efbda2174e0b334d2e81dc37d73921f545d76..89d7699a28cb1a130d8f91826dc0b9f6623bf230 100644
--- a/core/modules/ckeditor5/ckeditor5.module
+++ b/core/modules/ckeditor5/ckeditor5.module
@@ -22,6 +22,7 @@
 use Drupal\Core\Render\Element;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Url;
+use Drupal\editor\EditorInterface;
 use Symfony\Component\Validator\Constraints\Choice;
 
 /**
@@ -648,3 +649,34 @@ function _ckeditor5_theme_css($theme = NULL): array {
   }
   return $css;
 }
+
+/**
+ * Implements hook_ENTITY_TYPE_presave() for editor entities.
+ */
+function ckeditor5_editor_presave(EditorInterface $editor) {
+  if ($editor->getEditor() === 'ckeditor5') {
+    $settings = $editor->getSettings();
+    if (in_array('codeBlock', $settings['toolbar']['items'], TRUE) && !isset($settings['plugins']['ckeditor5_codeBlock'])) {
+      // @see \Drupal\ckeditor5\Plugin\CKEditor5Plugin\CodeBlock::defaultConfiguration()
+      $settings['plugins']['ckeditor5_codeBlock'] = [
+        'languages' => [
+          ['label' => 'Plain text', 'language' => 'plaintext'],
+          ['label' => 'C', 'language' => 'c'],
+          ['label' => 'C#', 'language' => 'cs'],
+          ['label' => 'C++', 'language' => 'cpp'],
+          ['label' => 'CSS', 'language' => 'css'],
+          ['label' => 'Diff', 'language' => 'diff'],
+          ['label' => 'HTML', 'language' => 'html'],
+          ['label' => 'Java', 'language' => 'java'],
+          ['label' => 'JavaScript', 'language' => 'javascript'],
+          ['label' => 'PHP', 'language' => 'php'],
+          ['label' => 'Python', 'language' => 'python'],
+          ['label' => 'Ruby', 'language' => 'ruby'],
+          ['label' => 'TypeScript', 'language' => 'typescript'],
+          ['label' => 'XML', 'language' => 'xml'],
+        ],
+      ];
+      $editor->setSettings($settings);
+    }
+  }
+}
diff --git a/core/modules/ckeditor5/ckeditor5.post_update.php b/core/modules/ckeditor5/ckeditor5.post_update.php
index 6f724b7473b472b130f572c954ebd6c9e93589dd..642673e182c3a9977fa3f3014f26c8359f734032 100644
--- a/core/modules/ckeditor5/ckeditor5.post_update.php
+++ b/core/modules/ckeditor5/ckeditor5.post_update.php
@@ -89,3 +89,18 @@ function ckeditor5_post_update_plugins_settings_export_order(&$sandbox = []) {
     return TRUE;
   });
 }
+
+/**
+ * Updates Text Editors using CKEditor 5 Code Block.
+ */
+function ckeditor5_post_update_code_block(&$sandbox = []) {
+  $config_entity_updater = \Drupal::classResolver(ConfigEntityUpdater::class);
+  $config_entity_updater->update($sandbox, 'editor', function (Editor $editor): bool {
+    // Only try to update editors using CKEditor 5.
+    if ($editor->getEditor() !== 'ckeditor5') {
+      return FALSE;
+    }
+    $settings = $editor->getSettings();
+    return in_array('codeBlock', $settings['toolbar']['items'], TRUE);
+  });
+}
diff --git a/core/modules/ckeditor5/config/schema/ckeditor5.schema.yml b/core/modules/ckeditor5/config/schema/ckeditor5.schema.yml
index cad0c764e7f62be63fd67a483f473a58c6d61164..82e201d415606c0d3cd1f78551ec54cd009404e9 100644
--- a/core/modules/ckeditor5/config/schema/ckeditor5.schema.yml
+++ b/core/modules/ckeditor5/config/schema/ckeditor5.schema.yml
@@ -141,6 +141,31 @@ ckeditor5.plugin.media_media:
       constraints:
         NotNull: []
 
+# Plugin \Drupal\ckeditor5\Plugin\CKEditor5Plugin\CodeBlock
+ckeditor5.plugin.ckeditor5_codeBlock:
+  type: mapping
+  label: Code Block
+  mapping:
+    languages:
+      type: sequence
+      orderby: ~
+      label: 'Languages'
+      constraints:
+        NotBlank:
+          message: "Enable at least one language, otherwise disable the Code Block plugin."
+        UniqueLabelInList:
+          labelKey: label
+      sequence:
+        type: mapping
+        label: 'Language'
+        mapping:
+          label:
+            type: label
+            label: 'Language label'
+          language:
+            type: string
+            label: 'Language key'
+
 # Plugin \Drupal\ckeditor5\Plugin\CKEditor5Plugin\Style
 ckeditor5.plugin.ckeditor5_style:
   type: mapping
diff --git a/core/modules/ckeditor5/src/Plugin/CKEditor5Plugin/CodeBlock.php b/core/modules/ckeditor5/src/Plugin/CKEditor5Plugin/CodeBlock.php
new file mode 100644
index 0000000000000000000000000000000000000000..364ca1733dac8ac328eace9dab89eefb91651669
--- /dev/null
+++ b/core/modules/ckeditor5/src/Plugin/CKEditor5Plugin/CodeBlock.php
@@ -0,0 +1,138 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\ckeditor5\Plugin\CKEditor5Plugin;
+
+use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableTrait;
+use Drupal\ckeditor5\Plugin\CKEditor5PluginDefault;
+use Drupal\ckeditor5\Plugin\CKEditor5PluginConfigurableInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\editor\EditorInterface;
+
+/**
+ * CKEditor 5 Code Block plugin configuration.
+ *
+ * @internal
+ *   Plugin classes are internal.
+ */
+class CodeBlock extends CKEditor5PluginDefault implements CKEditor5PluginConfigurableInterface {
+
+  use CKEditor5PluginConfigurableTrait;
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form['languages'] = [
+      '#title' => $this->t('Programming languages'),
+      '#type' => 'textarea',
+      '#description' => $this->t('A list of programming languages that will be provided in the "Code Block" dropdown. Enter one value per line, in the format key|label. Example: php|PHP.'),
+    ];
+    if (!empty($this->configuration['languages'])) {
+      $as_selectors = '';
+      foreach ($this->configuration['languages'] as $language) {
+        $as_selectors .= sprintf("%s|%s\n", $language['language'], $language['label']);
+      }
+      $form['languages']['#default_value'] = $as_selectors;
+    }
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $form_value = $form_state->getValue('languages');
+    [$styles, $unparseable_lines] = self::parseLanguagesFromValue($form_value);
+    if (!empty($unparseable_lines)) {
+      $line_numbers = array_keys($unparseable_lines);
+      $form_state->setError($form['languages'], $this->formatPlural(
+        count($unparseable_lines),
+        'Line @line-number does not contain a valid value. Enter a valid language key followed by a pipe symbol and a label.',
+        'Lines @line-numbers do not contain a valid value. Enter a valid language key followed by a pipe symbol and a label.',
+        [
+          '@line-number' => reset($line_numbers),
+          '@line-numbers' => implode(', ', $line_numbers),
+        ]
+      ));
+    }
+    $form_state->setValue('languages', $styles);
+  }
+
+  /**
+   * Parses the line-based (for form) Code Block configuration.
+   *
+   * @param string $form_value
+   *   A string containing >=1 lines with on each line a language key and label.
+   *
+   * @return array
+   *   The parsed equivalent: a list of arrays with each containing:
+   *   - label: the label after the pipe symbol, with whitespace trimmed
+   *   - language: the key for the language
+   */
+  protected static function parseLanguagesFromValue(string $form_value): array {
+    $unparseable_lines = [];
+
+    $lines = explode("\n", $form_value);
+    $languages = [];
+    foreach ($lines as $line) {
+      if (empty(trim($line))) {
+        continue;
+      }
+
+      // Parse the line.
+      [$language, $label] = array_map('trim', explode('|', $line));
+
+      $languages[] = [
+        'label' => $label,
+        'language' => $language,
+      ];
+    }
+    return [$languages, $unparseable_lines];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    $this->configuration['languages'] = $form_state->getValue('languages');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    return [
+      'languages' => [
+        ['language' => 'plaintext', 'label' => 'Plain text'],
+        ['language' => 'c', 'label' => 'C'],
+        ['language' => 'cs', 'label' => 'C#'],
+        ['language' => 'cpp', 'label' => 'C++'],
+        ['language' => 'css', 'label' => 'CSS'],
+        ['language' => 'diff', 'label' => 'Diff'],
+        ['language' => 'html', 'label' => 'HTML'],
+        ['language' => 'java', 'label' => 'Java'],
+        ['language' => 'javascript', 'label' => 'JavaScript'],
+        ['language' => 'php', 'label' => 'PHP'],
+        ['language' => 'python', 'label' => 'Python'],
+        ['language' => 'ruby', 'label' => 'Ruby'],
+        ['language' => 'typescript', 'label' => 'TypeScript'],
+        ['language' => 'xml', 'label' => 'XML'],
+      ],
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDynamicPluginConfig(array $static_plugin_config, EditorInterface $editor): array {
+    return [
+      'codeBlock' => [
+        'languages' => $this->configuration['languages'],
+      ],
+    ];
+  }
+
+}
diff --git a/core/modules/ckeditor5/tests/src/Functional/Update/CKEditor5UpdateCodeBlockConfigurationTest.php b/core/modules/ckeditor5/tests/src/Functional/Update/CKEditor5UpdateCodeBlockConfigurationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9bf6f3340399ec13366b52c9837448f58194c831
--- /dev/null
+++ b/core/modules/ckeditor5/tests/src/Functional/Update/CKEditor5UpdateCodeBlockConfigurationTest.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Drupal\Tests\ckeditor5\Functional\Update;
+
+use Drupal\editor\Entity\Editor;
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+
+/**
+ * @covers ckeditor5_post_update_code_block
+ * @group Update
+ * @group ckeditor5
+ */
+class CKEditor5UpdateCodeBlockConfigurationTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected $defaultTheme = 'stark';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-9.4.0.filled.standard.php.gz',
+    ];
+  }
+
+  /**
+   * Ensure default configuration for the CKEditor 5 codeBlock plugin is added.
+   */
+  public function testUpdateCodeBlockConfigurationPostUpdate(): void {
+    $editor = Editor::load('full_html');
+    $settings = $editor->getSettings();
+    $this->assertArrayNotHasKey('ckeditor5_codeBlock', $settings['plugins']);
+
+    $this->runUpdates();
+
+    $editor = Editor::load('full_html');
+    $settings = $editor->getSettings();
+    $this->assertArrayHasKey('ckeditor5_codeBlock', $settings['plugins']);
+    // @see \Drupal\ckeditor5\Plugin\CKEditor5Plugin\CodeBlock::defaultConfiguration()
+    $this->assertSame([
+      'languages' => [
+        ['label' => 'Plain text', 'language' => 'plaintext'],
+        ['label' => 'C', 'language' => 'c'],
+        ['label' => 'C#', 'language' => 'cs'],
+        ['label' => 'C++', 'language' => 'cpp'],
+        ['label' => 'CSS', 'language' => 'css'],
+        ['label' => 'Diff', 'language' => 'diff'],
+        ['label' => 'HTML', 'language' => 'html'],
+        ['label' => 'Java', 'language' => 'java'],
+        ['label' => 'JavaScript', 'language' => 'javascript'],
+        ['label' => 'PHP', 'language' => 'php'],
+        ['label' => 'Python', 'language' => 'python'],
+        ['label' => 'Ruby', 'language' => 'ruby'],
+        ['label' => 'TypeScript', 'language' => 'typescript'],
+        ['label' => 'XML', 'language' => 'xml'],
+      ],
+    ], $settings['plugins']['ckeditor5_codeBlock']);
+  }
+
+}
diff --git a/core/modules/ckeditor5/tests/src/Kernel/ConfigurablePluginTest.php b/core/modules/ckeditor5/tests/src/Kernel/ConfigurablePluginTest.php
index a786cb43325dbd016e3008ee8c293d8166a90c3c..f12a23ce6131c853c744971eb830727a147d6800 100644
--- a/core/modules/ckeditor5/tests/src/Kernel/ConfigurablePluginTest.php
+++ b/core/modules/ckeditor5/tests/src/Kernel/ConfigurablePluginTest.php
@@ -70,6 +70,24 @@ public function testDefaults() {
       'ckeditor5_sourceEditing' => [
         'allowed_tags' => [],
       ],
+      'ckeditor5_codeBlock' => [
+        'languages' => [
+          ['language' => 'plaintext', 'label' => 'Plain text'],
+          ['language' => 'c', 'label' => 'C'],
+          ['language' => 'cs', 'label' => 'C#'],
+          ['language' => 'cpp', 'label' => 'C++'],
+          ['language' => 'css', 'label' => 'CSS'],
+          ['language' => 'diff', 'label' => 'Diff'],
+          ['language' => 'html', 'label' => 'HTML'],
+          ['language' => 'java', 'label' => 'Java'],
+          ['language' => 'javascript', 'label' => 'JavaScript'],
+          ['language' => 'php', 'label' => 'PHP'],
+          ['language' => 'python', 'label' => 'Python'],
+          ['language' => 'ruby', 'label' => 'Ruby'],
+          ['language' => 'typescript', 'label' => 'TypeScript'],
+          ['language' => 'xml', 'label' => 'XML'],
+        ],
+      ],
       'ckeditor5_list' => [
         'reversed' => TRUE,
         'startIndex' => TRUE,
diff --git a/core/modules/ckeditor5/tests/src/Kernel/SmartDefaultSettingsTest.php b/core/modules/ckeditor5/tests/src/Kernel/SmartDefaultSettingsTest.php
index 4508759f83fc8117f3e26b32624557ad48ac1583..bf294d83752257485d05328f206e4aa630e3857f 100644
--- a/core/modules/ckeditor5/tests/src/Kernel/SmartDefaultSettingsTest.php
+++ b/core/modules/ckeditor5/tests/src/Kernel/SmartDefaultSettingsTest.php
@@ -903,7 +903,26 @@ public function provider() {
             ['codeBlock'],
           ),
         ],
-        'plugins' => $basic_html_test_case['expected_ckeditor5_settings']['plugins'],
+        'plugins' => [
+          'ckeditor5_codeBlock' => [
+            'languages' => [
+              ['label' => 'Plain text', 'language' => 'plaintext'],
+              ['label' => 'C', 'language' => 'c'],
+              ['label' => 'C#', 'language' => 'cs'],
+              ['label' => 'C++', 'language' => 'cpp'],
+              ['label' => 'CSS', 'language' => 'css'],
+              ['label' => 'Diff', 'language' => 'diff'],
+              ['label' => 'HTML', 'language' => 'html'],
+              ['label' => 'Java', 'language' => 'java'],
+              ['label' => 'JavaScript', 'language' => 'javascript'],
+              ['label' => 'PHP', 'language' => 'php'],
+              ['label' => 'Python', 'language' => 'python'],
+              ['label' => 'Ruby', 'language' => 'ruby'],
+              ['label' => 'TypeScript', 'language' => 'typescript'],
+              ['label' => 'XML', 'language' => 'xml'],
+            ],
+          ],
+        ] + $basic_html_test_case['expected_ckeditor5_settings']['plugins'],
       ],
       'expected_superset' => '<code class="language-*">',
       'expected_fundamental_compatibility_violations' => $basic_html_test_case['expected_fundamental_compatibility_violations'],
@@ -1215,6 +1234,24 @@ public function provider() {
           ],
         ],
         'plugins' => [
+          'ckeditor5_codeBlock' => [
+            'languages' => [
+              ['label' => 'Plain text', 'language' => 'plaintext'],
+              ['label' => 'C', 'language' => 'c'],
+              ['label' => 'C#', 'language' => 'cs'],
+              ['label' => 'C++', 'language' => 'cpp'],
+              ['label' => 'CSS', 'language' => 'css'],
+              ['label' => 'Diff', 'language' => 'diff'],
+              ['label' => 'HTML', 'language' => 'html'],
+              ['label' => 'Java', 'language' => 'java'],
+              ['label' => 'JavaScript', 'language' => 'javascript'],
+              ['label' => 'PHP', 'language' => 'php'],
+              ['label' => 'Python', 'language' => 'python'],
+              ['label' => 'Ruby', 'language' => 'ruby'],
+              ['label' => 'TypeScript', 'language' => 'typescript'],
+              ['label' => 'XML', 'language' => 'xml'],
+            ],
+          ],
           'ckeditor5_heading' => [
             'enabled_headings' => [
               'heading2',
diff --git a/core/modules/ckeditor5/tests/src/Nightwatch/Tests/ckEditor5CodeSyntaxTest.js b/core/modules/ckeditor5/tests/src/Nightwatch/Tests/ckEditor5CodeSyntaxTest.js
new file mode 100644
index 0000000000000000000000000000000000000000..f88f79f05241b1667c2bec47254a85acfeb3d1af
--- /dev/null
+++ b/core/modules/ckeditor5/tests/src/Nightwatch/Tests/ckEditor5CodeSyntaxTest.js
@@ -0,0 +1,133 @@
+module.exports = {
+  '@tags': ['core', 'ckeditor5'],
+  before(browser) {
+    browser.drupalInstall({ installProfile: 'minimal' });
+  },
+  after(browser) {
+    browser.drupalUninstall();
+  },
+  'Verify code block configured languages are respected': (browser) => {
+    browser.drupalLoginAsAdmin(() => {
+      browser
+        // Enable required modules.
+        .drupalRelativeURL('/admin/modules')
+        .click('[name="modules[ckeditor5][enable]"]')
+        .click('[name="modules[field_ui][enable]"]')
+        .submitForm('input[type="submit"]') // Submit module form.
+        .waitForElementVisible(
+          '.system-modules-confirm-form input[value="Continue"]',
+        )
+        .submitForm('input[value="Continue"]') // Confirm installation of dependencies.
+        .waitForElementVisible('.system-modules', 10000)
+
+        // Create new input format.
+        .drupalRelativeURL('/admin/config/content/formats/add')
+        .waitForElementVisible('[data-drupal-selector="edit-name"]')
+        .updateValue('[data-drupal-selector="edit-name"]', 'test')
+        .waitForElementVisible('#edit-name-machine-name-suffix')
+        .click(
+          '[data-drupal-selector="edit-editor-editor"] option[value=ckeditor5]',
+        )
+        // Wait for CKEditor 5 settings to be visible.
+        .waitForElementVisible(
+          '[data-drupal-selector="edit-editor-settings-toolbar"]',
+        )
+        .click('.ckeditor5-toolbar-button-sourceEditing') // Select the Source Editing button.
+        .keys(browser.Keys.DOWN) // Hit the down arrow key to move it to the toolbar.
+        // Wait for new source editing vertical tab to be present before continuing.
+        .waitForElementVisible(
+          '[href*=edit-editor-settings-plugins-ckeditor5-sourceediting]',
+        )
+        .click('.ckeditor5-toolbar-item-codeBlock') // Select the Code Block button.
+        .keys(browser.Keys.DOWN) // Hit the down arrow key to move it to the toolbar.
+        // Wait for new code editing vertical tab to be present before continuing.
+        .waitForElementVisible(
+          '[href*=edit-editor-settings-plugins-ckeditor5-codeblock]',
+        )
+        .click('[href*=edit-editor-settings-plugins-ckeditor5-codeblock]')
+        .setValue(
+          '[data-drupal-selector="edit-editor-settings-plugins-ckeditor5-codeblock-languages"]',
+          'twig|Twig\nyml|YML',
+        )
+        .submitForm('input[type="submit"]')
+        .waitForElementVisible('[data-drupal-messages]')
+        .assert.textContains('[data-drupal-messages]', 'Added text format')
+
+        // Create a new content type.
+        .drupalRelativeURL('/admin/structure/types/add')
+        .waitForElementVisible('[data-drupal-selector="edit-name"]')
+        .updateValue('[data-drupal-selector="edit-name"]', 'test')
+        .waitForElementVisible('#edit-name-machine-name-suffix') // Wait for machine name to update.
+        .submitForm('input[type="submit"]')
+        .waitForElementVisible('[data-drupal-messages]')
+        .assert.textContains(
+          '[data-drupal-messages]',
+          'The content type test has been added',
+        )
+
+        // Navigate to create new content.
+        .drupalRelativeURL('/node/add/test')
+        .waitForElementVisible('.ck-editor__editable')
+
+        // Open code block dropdown, and verify that correct languages are present.
+        .click(
+          '.ck-code-block-dropdown .ck-dropdown__button .ck-splitbutton__arrow',
+        )
+        .assert.containsText(
+          '.ck-code-block-dropdown .ck-dropdown__panel .ck-list__item:nth-child(1) .ck-button__label',
+          'Twig',
+        )
+        .assert.containsText(
+          '.ck-code-block-dropdown .ck-dropdown__panel .ck-list__item:nth-child(2) .ck-button__label',
+          'YML',
+        )
+
+        // Click the first language (which should be 'Twig').
+        .click(
+          '.ck-code-block-dropdown .ck-dropdown__panel .ck-list__item:nth-child(1) button',
+        )
+        .waitForElementVisible('.ck-editor__main pre[data-language="Twig"]')
+        .keys('x') // Press 'X' to ensure there's data in CKEditor before switching to source view.
+        .pause(50)
+
+        // Go into source editing and verify that correct CSS class is added.
+        .click('.ck-source-editing-button')
+        .waitForElementVisible('.ck-source-editing-area')
+        .assert.valueContains(
+          '.ck-source-editing-area textarea',
+          '<pre><code class="language-twig">',
+        )
+
+        // Go back into WYSIWYG mode and hit enter three times to break out of code block.
+        .click('.ck-source-editing-button') // Disable source editing.
+        .waitForElementVisible('.ck-editor__editable:not(.ck-hidden)')
+        .keys(browser.Keys.RIGHT) // Go to end of line.
+        .pause(50)
+
+        // Hit Enter three times to break out of CKEditor's code block.
+        .keys(browser.Keys.ENTER)
+        .pause(50)
+        .keys(browser.Keys.ENTER)
+        .pause(50)
+        .keys(browser.Keys.ENTER)
+        .pause(50)
+
+        // Open up the code syntax dropdown, and click the 2nd item (which should be 'YML').
+        .click(
+          '.ck-code-block-dropdown .ck-dropdown__button .ck-splitbutton__arrow',
+        )
+        .click(
+          '.ck-code-block-dropdown .ck-dropdown__panel .ck-list__item:nth-child(2) button',
+        )
+        .keys('x') // Press 'X' to ensure there's data in CKEditor before switching to source view.
+
+        // Go into source editing and verify that correct CSS class is added.
+        .click('.ck-source-editing-button')
+        .waitForElementVisible('.ck-source-editing-area')
+        .assert.valueContains(
+          '.ck-source-editing-area textarea',
+          '<pre><code class="language-yml">',
+        );
+    });
+  },
+};
diff --git a/core/profiles/standard/config/install/editor.editor.full_html.yml b/core/profiles/standard/config/install/editor.editor.full_html.yml
index babf6b59e04d6228ced44158b5c0d284ffd8cbfe..efe9de4a6c5d0b5203d998c697c8281033236010 100644
--- a/core/profiles/standard/config/install/editor.editor.full_html.yml
+++ b/core/profiles/standard/config/install/editor.editor.full_html.yml
@@ -32,6 +32,50 @@ settings:
       - '|'
       - sourceEditing
   plugins:
+    ckeditor5_codeBlock:
+      languages:
+        -
+          label: 'Plain text'
+          language: plaintext
+        -
+          label: C
+          language: c
+        -
+          label: 'C#'
+          language: cs
+        -
+          label: C++
+          language: cpp
+        -
+          label: CSS
+          language: css
+        -
+          label: Diff
+          language: diff
+        -
+          label: HTML
+          language: html
+        -
+          label: Java
+          language: java
+        -
+          label: JavaScript
+          language: javascript
+        -
+          label: PHP
+          language: php
+        -
+          label: Python
+          language: python
+        -
+          label: Ruby
+          language: ruby
+        -
+          label: TypeScript
+          language: typescript
+        -
+          label: XML
+          language: xml
     ckeditor5_heading:
       enabled_headings:
         - heading2