diff --git a/packages/block-library/src/index.js b/packages/block-library/src/index.js
index 5ad6a33fd2ac0..242fa05490313 100644
--- a/packages/block-library/src/index.js
+++ b/packages/block-library/src/index.js
@@ -80,6 +80,7 @@ import * as postDate from './post-date';
import * as postExcerpt from './post-excerpt';
import * as postFeaturedImage from './post-featured-image';
import * as postTags from './post-tags';
+import * as postCategories from './post-categories';
/**
* Function to register an individual block.
diff --git a/packages/block-library/src/post-categories/block.json b/packages/block-library/src/post-categories/block.json
new file mode 100644
index 0000000000000..731b2e370a180
--- /dev/null
+++ b/packages/block-library/src/post-categories/block.json
@@ -0,0 +1,20 @@
+{
+ "name": "core/post-categories",
+ "category": "layout",
+ "context": [ "postId" ],
+ "attributes": {
+ "align": {
+ "type": "string",
+ "enum": [
+ "left",
+ "center",
+ "right",
+ "wide",
+ "full"
+ ]
+ },
+ "className": {
+ "type": "string"
+ }
+ }
+}
diff --git a/packages/block-library/src/post-categories/edit.js b/packages/block-library/src/post-categories/edit.js
new file mode 100644
index 0000000000000..1c59552a0aa39
--- /dev/null
+++ b/packages/block-library/src/post-categories/edit.js
@@ -0,0 +1,42 @@
+/**
+ * WordPress dependencies
+ */
+import { useEntityProp, useEntityId } from '@wordpress/core-data';
+import { useSelect } from '@wordpress/data';
+import { __ } from '@wordpress/i18n';
+
+function PostCategoriesDisplay() {
+ const [ categories ] = useEntityProp( 'postType', 'post', 'categories' );
+ const categoryLinks = useSelect(
+ ( select ) => {
+ const { getEntityRecord } = select( 'core' );
+ let loaded = true;
+ const links = categories.map( ( categoryId ) => {
+ const category = getEntityRecord('taxonomy', 'category', categoryId );
+ if ( ! category ) {
+ return ( loaded = false );
+ }
+ return (
+
+ { category.name }
+
+ );
+ } );
+ return loaded && links;
+ },
+ [ categories ]
+ );
+ return (
+ categoryLinks &&
+ ( categoryLinks.length === 0
+ ? __( 'No categories.' )
+ : categoryLinks.reduce( ( prev, curr ) => [ prev, ', ', curr ] ) )
+ );
+}
+
+export default function PostCategoriesEdit() {
+ if ( ! useEntityId( 'postType', 'post' ) ) {
+ return 'Post Categories Placeholder';
+ }
+ return ;
+}
diff --git a/packages/block-library/src/post-categories/index.js b/packages/block-library/src/post-categories/index.js
new file mode 100644
index 0000000000000..4ed37d3394ddd
--- /dev/null
+++ b/packages/block-library/src/post-categories/index.js
@@ -0,0 +1,25 @@
+/**
+ * WordPress dependencies
+ */
+import { category as icon } from '@wordpress/icons';
+import { __ } from '@wordpress/i18n';
+
+/**
+ * Internal dependencies
+ */
+import metadata from './block.json';
+import edit from './edit';
+
+const { name } = metadata;
+
+export { metadata, name };
+
+export const settings = {
+ title: __( 'Post Categories' ),
+ description: __('Display a list of categories for this post.'),
+ icon,
+ supports: {
+ align: true,
+ },
+ edit,
+};
diff --git a/packages/block-library/src/post-categories/index.php b/packages/block-library/src/post-categories/index.php
new file mode 100644
index 0000000000000..07698fe86d843
--- /dev/null
+++ b/packages/block-library/src/post-categories/index.php
@@ -0,0 +1,57 @@
+context['postId'] ) ) {
+ return '';
+ }
+
+ $class = 'wp-block-post-categories';
+
+ if ( isset( $attributes['align'] ) ) {
+ $class .= " align{$attributes['align']}";
+ }
+
+ if ( isset( $attributes['className'] ) ) {
+ $class .= " {$attributes['className']}";
+ }
+
+ $post_categories = get_the_category( $block->context['postId'] );
+ if ( ! empty( $post_categories ) ) {
+ $output = '';
+ foreach ( $post_categories as $category ) {
+ $output .= '' . $category->name . '' . ', ';
+ }
+ return sprintf(
+ '
' . __( 'Categories' ) . ' %2$s
',
+ esc_attr( $class ),
+ trim( $output, ', ' )
+ );
+
+ }
+}
+
+/**
+ * Registers the `core/post-categories` block on the server.
+ */
+function register_block_core_post_categories() {
+ register_block_type_from_metadata(
+ __DIR__ . '/post-categories',
+ array(
+ 'render_callback' => 'render_block_core_post_categories',
+ )
+ );
+}
+add_action( 'init', 'register_block_core_post_categories' );
diff --git a/packages/e2e-tests/fixtures/blocks/core__post-categories.html b/packages/e2e-tests/fixtures/blocks/core__post-categories.html
new file mode 100644
index 0000000000000..b4bbf67e7b61a
--- /dev/null
+++ b/packages/e2e-tests/fixtures/blocks/core__post-categories.html
@@ -0,0 +1 @@
+
diff --git a/packages/e2e-tests/fixtures/blocks/core__post-categories.json b/packages/e2e-tests/fixtures/blocks/core__post-categories.json
new file mode 100644
index 0000000000000..502199eb8a3d9
--- /dev/null
+++ b/packages/e2e-tests/fixtures/blocks/core__post-categories.json
@@ -0,0 +1,10 @@
+[
+ {
+ "clientId": "_clientId_0",
+ "name": "core/post-categories",
+ "isValid": true,
+ "attributes": {},
+ "innerBlocks": [],
+ "originalContent": ""
+ }
+]
diff --git a/packages/e2e-tests/fixtures/blocks/core__post-categories.parsed.json b/packages/e2e-tests/fixtures/blocks/core__post-categories.parsed.json
new file mode 100644
index 0000000000000..d284c12916466
--- /dev/null
+++ b/packages/e2e-tests/fixtures/blocks/core__post-categories.parsed.json
@@ -0,0 +1,18 @@
+[
+ {
+ "blockName": "core/post-categories",
+ "attrs": {},
+ "innerBlocks": [],
+ "innerHTML": "",
+ "innerContent": []
+ },
+ {
+ "blockName": null,
+ "attrs": {},
+ "innerBlocks": [],
+ "innerHTML": "\n",
+ "innerContent": [
+ "\n"
+ ]
+ }
+]
diff --git a/packages/e2e-tests/fixtures/blocks/core__post-categories.serialized.html b/packages/e2e-tests/fixtures/blocks/core__post-categories.serialized.html
new file mode 100644
index 0000000000000..b4bbf67e7b61a
--- /dev/null
+++ b/packages/e2e-tests/fixtures/blocks/core__post-categories.serialized.html
@@ -0,0 +1 @@
+