diff --git a/openstackclient/tests/unit/volume/v2/test_volume_type.py b/openstackclient/tests/unit/volume/v2/test_volume_type.py
index 0f6e65a220..5e7b2a6e7c 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume_type.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume_type.py
@@ -46,18 +46,19 @@ class TestType(volume_fakes.TestVolume):
 
 
 class TestTypeCreate(TestType):
-    project = identity_fakes.FakeProject.create_one_project()
-    columns = (
-        'description',
-        'id',
-        'is_public',
-        'name',
-    )
-
     def setUp(self):
         super().setUp()
 
-        self.new_volume_type = volume_fakes.create_one_volume_type()
+        self.new_volume_type = volume_fakes.create_one_volume_type(
+            methods={'set_keys': None},
+        )
+        self.project = identity_fakes.FakeProject.create_one_project()
+        self.columns = (
+            'description',
+            'id',
+            'is_public',
+            'name',
+        )
         self.data = (
             self.new_volume_type.description,
             self.new_volume_type.id,
@@ -121,7 +122,45 @@ class TestTypeCreate(TestType):
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data, data)
 
-    def test_public_type_create_with_project(self):
+    def test_type_create_with_properties(self):
+        arglist = [
+            '--property',
+            'myprop=myvalue',
+            # this combination isn't viable server-side but is okay for testing
+            '--multiattach',
+            '--cacheable',
+            '--replicated',
+            self.new_volume_type.name,
+        ]
+        verifylist = [
+            ('properties', {'myprop': 'myvalue'}),
+            ('multiattach', True),
+            ('cacheable', True),
+            ('replicated', True),
+            ('name', self.new_volume_type.name),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+        self.volume_types_mock.create.assert_called_with(
+            self.new_volume_type.name, description=None
+        )
+        self.new_volume_type.set_keys.assert_called_once_with(
+            {
+                'myprop': 'myvalue',
+                'multiattach': '<is> True',
+                'cacheable': '<is> True',
+                'replication_enabled': '<is> True',
+            }
+        )
+
+        self.columns += ('properties',)
+        self.data += (format_columns.DictColumn(None),)
+
+        self.assertEqual(self.columns, columns)
+        self.assertCountEqual(self.data, data)
+
+    def test_public_type_create_with_project_public(self):
         arglist = [
             '--project',
             self.project.id,
@@ -134,7 +173,9 @@ class TestTypeCreate(TestType):
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         self.assertRaises(
-            exceptions.CommandError, self.cmd.take_action, parsed_args
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args,
         )
 
     def test_type_create_with_encryption(self):
@@ -388,47 +429,60 @@ class TestTypeList(TestType):
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data_with_default_type, list(data))
 
-    def test_type_list_with_property_option(self):
+    def test_type_list_with_properties(self):
         self.app.client_manager.volume.api_version = api_versions.APIVersion(
             '3.52'
         )
 
         arglist = [
             "--property",
-            "multiattach=<is> True",
+            "foo=bar",
+            "--multiattach",
+            "--cacheable",
+            "--replicated",
         ]
         verifylist = [
             ("encryption_type", False),
             ("long", False),
             ("is_public", None),
             ("default", False),
-            ("properties", {"multiattach": "<is> True"}),
+            ("properties", {"foo": "bar"}),
+            ("multiattach", True),
+            ("cacheable", True),
+            ("replicated", True),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
         columns, data = self.cmd.take_action(parsed_args)
         self.volume_types_mock.list.assert_called_once_with(
-            search_opts={"extra_specs": {"multiattach": "<is> True"}},
+            search_opts={
+                "extra_specs": {
+                    "foo": "bar",
+                    "multiattach": "<is> True",
+                    "cacheable": "<is> True",
+                    "replication_enabled": "<is> True",
+                }
+            },
             is_public=None,
         )
         self.assertEqual(self.columns, columns)
         self.assertCountEqual(self.data, list(data))
 
-    def test_type_list_with_property_option_pre_v352(self):
+    def test_type_list_with_properties_pre_v352(self):
         self.app.client_manager.volume.api_version = api_versions.APIVersion(
             '3.51'
         )
 
         arglist = [
             "--property",
-            "multiattach=<is> True",
+            "foo=bar",
         ]
         verifylist = [
             ("encryption_type", False),
             ("long", False),
             ("is_public", None),
             ("default", False),
-            ("properties", {"multiattach": "<is> True"}),
+            ("properties", {"foo": "bar"}),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
@@ -547,12 +601,19 @@ class TestTypeSet(TestType):
         arglist = [
             '--property',
             'myprop=myvalue',
+            # this combination isn't viable server-side but is okay for testing
+            '--multiattach',
+            '--cacheable',
+            '--replicated',
             self.volume_type.id,
         ]
         verifylist = [
             ('name', None),
             ('description', None),
             ('properties', {'myprop': 'myvalue'}),
+            ('multiattach', True),
+            ('cacheable', True),
+            ('replicated', True),
             ('volume_type', self.volume_type.id),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -561,7 +622,12 @@ class TestTypeSet(TestType):
         self.assertIsNone(result)
 
         self.volume_type.set_keys.assert_called_once_with(
-            {'myprop': 'myvalue'}
+            {
+                'myprop': 'myvalue',
+                'multiattach': '<is> True',
+                'cacheable': '<is> True',
+                'replication_enabled': '<is> True',
+            }
         )
         self.volume_type_access_mock.add_project_access.assert_not_called()
         self.volume_encryption_types_mock.update.assert_not_called()
diff --git a/openstackclient/volume/v2/volume_type.py b/openstackclient/volume/v2/volume_type.py
index bf10a2e545..c8e5627431 100644
--- a/openstackclient/volume/v2/volume_type.py
+++ b/openstackclient/volume/v2/volume_type.py
@@ -146,14 +146,45 @@ class CreateVolumeType(command.ShowOne):
                 '(repeat option to set multiple properties)'
             ),
         )
+        parser.add_argument(
+            '--multiattach',
+            action='store_true',
+            default=False,
+            help=_(
+                "Enable multi-attach for this volume type "
+                "(this is an alias for '--property multiattach=<is> True') "
+                "(requires driver support)"
+            ),
+        )
+        parser.add_argument(
+            '--cacheable',
+            action='store_true',
+            default=False,
+            help=_(
+                "Enable caching for this volume type "
+                "(this is an alias for '--property cacheable=<is> True') "
+                "(requires driver support)"
+            ),
+        )
+        parser.add_argument(
+            '--replicated',
+            action='store_true',
+            default=False,
+            help=_(
+                "Enabled replication for this volume type "
+                "(this is an alias for '--property replication_enabled=<is> True') "  # noqa: E501
+                "(requires driver support)"
+            ),
+        )
         parser.add_argument(
             '--project',
             metavar='<project>',
             help=_(
                 "Allow <project> to access private type (name or ID) "
-                "(Must be used with --private option)"
+                "(must be used with --private option)"
             ),
         )
+        identity_common.add_project_domain_option_to_parser(parser)
         # TODO(Huanxuan Ao): Add choices for each "--encryption-*" option.
         parser.add_argument(
             '--encryption-provider',
@@ -161,8 +192,8 @@ class CreateVolumeType(command.ShowOne):
             help=_(
                 'Set the encryption provider format for '
                 'this volume type (e.g "luks" or "plain") (admin only) '
-                '(This option is required when setting encryption type '
-                'of a volume. Consider using other encryption options '
+                '(this option is required when setting encryption type '
+                'of a volume; consider using other encryption options '
                 'such as: "--encryption-cipher", "--encryption-key-size" '
                 'and "--encryption-control-location")'
             ),
@@ -198,7 +229,6 @@ class CreateVolumeType(command.ShowOne):
                 '"--encryption-provider")'
             ),
         )
-        identity_common.add_project_domain_option_to_parser(parser)
         return parser
 
     def take_action(self, parsed_args):
@@ -235,8 +265,17 @@ class CreateVolumeType(command.ShowOne):
                 )
                 LOG.error(msg % {'project': parsed_args.project, 'e': e})
 
+        properties = {}
         if parsed_args.properties:
-            result = volume_type.set_keys(parsed_args.properties)
+            properties.update(parsed_args.properties)
+        if parsed_args.multiattach:
+            properties['multiattach'] = '<is> True'
+        if parsed_args.cacheable:
+            properties['cacheable'] = '<is> True'
+        if parsed_args.replicated:
+            properties['replication_enabled'] = '<is> True'
+        if properties:
+            result = volume_type.set_keys(properties)
             volume_type._info.update(
                 {'properties': format_columns.DictColumn(result)}
             )
@@ -365,6 +404,37 @@ class ListVolumeType(command.Lister):
                 '(supported by --os-volume-api-version 3.52 or above)'
             ),
         )
+        parser.add_argument(
+            '--multiattach',
+            action='store_true',
+            default=False,
+            help=_(
+                "List only volume types with multi-attach enabled "
+                "(this is an alias for '--property multiattach=<is> True') "
+                "(supported by --os-volume-api-version 3.52 or above)"
+            ),
+        )
+        parser.add_argument(
+            '--cacheable',
+            action='store_true',
+            default=False,
+            help=_(
+                "List only volume types with caching enabled "
+                "(this is an alias for '--property cacheable=<is> True') "
+                "(admin only) "
+                "(supported by --os-volume-api-version 3.52 or above)"
+            ),
+        )
+        parser.add_argument(
+            '--replicated',
+            action='store_true',
+            default=False,
+            help=_(
+                "List only volume types with replication enabled "
+                "(this is an alias for '--property replication_enabled=<is> True') "  # noqa: E501
+                "(supported by --os-volume-api-version 3.52 or above)"
+            ),
+        )
         return parser
 
     def take_action(self, parsed_args):
@@ -393,17 +463,25 @@ class ListVolumeType(command.Lister):
             data = [volume_client.volume_types.default()]
         else:
             search_opts = {}
-
+            properties = {}
             if parsed_args.properties:
+                properties.update(parsed_args.properties)
+            if parsed_args.multiattach:
+                properties['multiattach'] = '<is> True'
+            if parsed_args.cacheable:
+                properties['cacheable'] = '<is> True'
+            if parsed_args.replicated:
+                properties['replication_enabled'] = '<is> True'
+            if properties:
                 if volume_client.api_version < api_versions.APIVersion('3.52'):
                     msg = _(
                         "--os-volume-api-version 3.52 or greater is required "
-                        "to use the '--property' option"
+                        "to use the '--property' option or any of the alias "
+                        "options"
                     )
                     raise exceptions.CommandError(msg)
 
-                # we pass this through as-is
-                search_opts['extra_specs'] = parsed_args.properties
+                search_opts['extra_specs'] = properties
 
             data = volume_client.volume_types.list(
                 search_opts=search_opts,
@@ -482,6 +560,36 @@ class SetVolumeType(command.Command):
                 '(repeat option to set multiple properties)'
             ),
         )
+        parser.add_argument(
+            '--multiattach',
+            action='store_true',
+            default=False,
+            help=_(
+                "Enable multi-attach for this volume type "
+                "(this is an alias for '--property multiattach=<is> True') "
+                "(requires driver support)"
+            ),
+        )
+        parser.add_argument(
+            '--cacheable',
+            action='store_true',
+            default=False,
+            help=_(
+                "Enable caching for this volume type "
+                "(this is an alias for '--property cacheable=<is> True') "
+                "(requires driver support)"
+            ),
+        )
+        parser.add_argument(
+            '--replicated',
+            action='store_true',
+            default=False,
+            help=_(
+                "Enabled replication for this volume type "
+                "(this is an alias for '--property replication_enabled=<is> True') "  # noqa: E501
+                "(requires driver support)"
+            ),
+        )
         parser.add_argument(
             '--project',
             metavar='<project>',
@@ -587,11 +695,22 @@ class SetVolumeType(command.Command):
                 )
                 result += 1
 
+        properties = {}
+
+        properties = {}
         if parsed_args.properties:
+            properties.update(parsed_args.properties)
+        if parsed_args.multiattach:
+            properties['multiattach'] = '<is> True'
+        if parsed_args.cacheable:
+            properties['cacheable'] = '<is> True'
+        if parsed_args.replicated:
+            properties['replication_enabled'] = '<is> True'
+        if properties:
             try:
-                volume_type.set_keys(parsed_args.properties)
+                volume_type.set_keys(properties)
             except Exception as e:
-                LOG.error(_("Failed to set volume type property: %s"), e)
+                LOG.error(_("Failed to set volume type properties: %s"), e)
                 result += 1
 
         if parsed_args.project:
@@ -760,7 +879,7 @@ class UnsetVolumeType(command.Command):
             try:
                 volume_type.unset_keys(parsed_args.properties)
             except Exception as e:
-                LOG.error(_("Failed to unset volume type property: %s"), e)
+                LOG.error(_("Failed to unset volume type properties: %s"), e)
                 result += 1
 
         if parsed_args.project:
diff --git a/releasenotes/notes/volume-type-extra-specs-22a22fcb6e269832.yaml b/releasenotes/notes/volume-type-extra-specs-22a22fcb6e269832.yaml
new file mode 100644
index 0000000000..fb30f98cf6
--- /dev/null
+++ b/releasenotes/notes/volume-type-extra-specs-22a22fcb6e269832.yaml
@@ -0,0 +1,7 @@
+---
+features:
+  - |
+    The ``volume type create``, ``volume type set``, ``volume type list``
+    commands now accept three new options - ``--multiattach``, ``--cacheable``,
+    and ``--replicated`` - which are short cuts for setting or filtering on
+    the relevant properties on the volume type.