diff --git a/doc/source/cli/command-objects/quota.rst b/doc/source/cli/command-objects/quota.rst
index f39536af8e..c538cfb3dd 100644
--- a/doc/source/cli/command-objects/quota.rst
+++ b/doc/source/cli/command-objects/quota.rst
@@ -17,6 +17,8 @@ List quotas for all projects with non-default quota values
 
     openstack quota list
         --compute | --network | --volume
+        [--project <project>]
+        [--detail]
 
 .. option:: --network
 
@@ -30,6 +32,14 @@ List quotas for all projects with non-default quota values
 
     List volume quotas
 
+.. option:: --project <project>
+
+    List quotas for this project <project> (name or ID)
+
+.. option:: --detail
+
+    Show details about quotas usage
+
 quota set
 ---------
 
diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index 282ea4284d..dba6873ff9 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -97,12 +97,164 @@ def _xform_get_quota(data, value, keys):
     return res
 
 
-class ListQuota(command.Lister):
-    _description = _("List quotas for all projects "
-                     "with non-default quota values")
+class BaseQuota(object):
+    def _get_project(self, parsed_args):
+        if parsed_args.project is not None:
+            identity_client = self.app.client_manager.identity
+            project = utils.find_resource(
+                identity_client.projects,
+                parsed_args.project,
+            )
+            project_id = project.id
+            project_name = project.name
+        elif self.app.client_manager.auth_ref:
+            # Get the project from the current auth
+            project = self.app.client_manager.auth_ref
+            project_id = project.project_id
+            project_name = project.project_name
+        else:
+            project = None
+            project_id = None
+            project_name = None
+        project_info = {}
+        project_info['id'] = project_id
+        project_info['name'] = project_name
+        return project_info
+
+    def get_compute_quota(self, client, parsed_args):
+        quota_class = (
+            parsed_args.quota_class if 'quota_class' in parsed_args else False)
+        detail = parsed_args.detail if 'detail' in parsed_args else False
+        default = parsed_args.default if 'default' in parsed_args else False
+        try:
+            if quota_class:
+                quota = client.quota_classes.get(parsed_args.project)
+            else:
+                project_info = self._get_project(parsed_args)
+                project = project_info['id']
+                if default:
+                    quota = client.quotas.defaults(project)
+                else:
+                    quota = client.quotas.get(project, detail=detail)
+        except Exception as e:
+            if type(e).__name__ == 'EndpointNotFound':
+                return {}
+            else:
+                raise
+        return quota._info
+
+    def get_volume_quota(self, client, parsed_args):
+        quota_class = (
+            parsed_args.quota_class if 'quota_class' in parsed_args else False)
+        default = parsed_args.default if 'default' in parsed_args else False
+        try:
+            if quota_class:
+                quota = client.quota_classes.get(parsed_args.project)
+            else:
+                project_info = self._get_project(parsed_args)
+                project = project_info['id']
+                if default:
+                    quota = client.quotas.defaults(project)
+                else:
+                    quota = client.quotas.get(project)
+        except Exception as e:
+            if type(e).__name__ == 'EndpointNotFound':
+                return {}
+            else:
+                raise
+        return quota._info
+
+    def get_network_quota(self, parsed_args):
+        quota_class = (
+            parsed_args.quota_class if 'quota_class' in parsed_args else False)
+        detail = parsed_args.detail if 'detail' in parsed_args else False
+        default = parsed_args.default if 'default' in parsed_args else False
+        if quota_class:
+            return {}
+        if self.app.client_manager.is_network_endpoint_enabled():
+            project_info = self._get_project(parsed_args)
+            project = project_info['id']
+            client = self.app.client_manager.network
+            if default:
+                network_quota = client.get_quota_default(project)
+                if type(network_quota) is not dict:
+                    network_quota = network_quota.to_dict()
+            else:
+                network_quota = client.get_quota(project,
+                                                 details=detail)
+                if type(network_quota) is not dict:
+                    network_quota = network_quota.to_dict()
+                if detail:
+                    # NOTE(slaweq): Neutron returns values with key "used" but
+                    # Nova for example returns same data with key "in_use"
+                    # instead.
+                    # Because of that we need to convert Neutron key to
+                    # the same as is returned from Nova to make result
+                    # more consistent
+                    for key, values in network_quota.items():
+                        if type(values) is dict and "used" in values:
+                            values[u'in_use'] = values.pop("used")
+                        network_quota[key] = values
+            return network_quota
+        else:
+            return {}
+
+
+class ListQuota(command.Lister, BaseQuota):
+    _description = _(
+        "List quotas for all projects with non-default quota values or "
+        "list detailed quota informations for requested project")
+
+    def _get_detailed_quotas(self, parsed_args):
+        columns = (
+            'resource',
+            'in_use',
+            'reserved',
+            'limit'
+        )
+        column_headers = (
+            'Resource',
+            'In Use',
+            'Reserved',
+            'Limit'
+        )
+        quotas = {}
+        if parsed_args.compute:
+            quotas.update(self.get_compute_quota(
+                self.app.client_manager.compute, parsed_args))
+        if parsed_args.network:
+            quotas.update(self.get_network_quota(parsed_args))
+
+        result = []
+        for resource, values in quotas.items():
+            # NOTE(slaweq): there is no detailed quotas info for some resources
+            # and it should't be displayed here
+            if type(values) is dict:
+                result.append({
+                    'resource': resource,
+                    'in_use': values.get('in_use'),
+                    'reserved': values.get('reserved'),
+                    'limit': values.get('limit')
+                })
+        return (column_headers,
+                (utils.get_dict_properties(
+                    s, columns,
+                ) for s in result))
 
     def get_parser(self, prog_name):
         parser = super(ListQuota, self).get_parser(prog_name)
+        parser.add_argument(
+            '--project',
+            metavar='<project>',
+            help=_('List quotas for this project <project> (name or ID)'),
+        )
+        parser.add_argument(
+            '--detail',
+            dest='detail',
+            action='store_true',
+            default=False,
+            help=_('Show details about quotas usage')
+        )
         option = parser.add_mutually_exclusive_group(required=True)
         option.add_argument(
             '--compute',
@@ -130,6 +282,8 @@ class ListQuota(command.Lister):
         project_ids = [getattr(p, 'id', '') for p in projects]
 
         if parsed_args.compute:
+            if parsed_args.detail:
+                return self._get_detailed_quotas(parsed_args)
             compute_client = self.app.client_manager.compute
             for p in project_ids:
                 try:
@@ -193,6 +347,9 @@ class ListQuota(command.Lister):
                     ) for s in result))
 
         if parsed_args.volume:
+            if parsed_args.detail:
+                LOG.warning("Volume service doesn't provide detailed quota"
+                            " information")
             volume_client = self.app.client_manager.volume
             for p in project_ids:
                 try:
@@ -243,6 +400,8 @@ class ListQuota(command.Lister):
                     ) for s in result))
 
         if parsed_args.network:
+            if parsed_args.detail:
+                return self._get_detailed_quotas(parsed_args)
             client = self.app.client_manager.network
             for p in project_ids:
                 try:
@@ -410,7 +569,7 @@ class SetQuota(command.Command):
                     **network_kwargs)
 
 
-class ShowQuota(command.ShowOne):
+class ShowQuota(command.ShowOne, BaseQuota):
     _description = _("Show quotas for project or class")
 
     def get_parser(self, prog_name):
@@ -438,62 +597,6 @@ class ShowQuota(command.ShowOne):
         )
         return parser
 
-    def _get_project(self, parsed_args):
-        if parsed_args.project is not None:
-            identity_client = self.app.client_manager.identity
-            project = utils.find_resource(
-                identity_client.projects,
-                parsed_args.project,
-            )
-            project_id = project.id
-            project_name = project.name
-        elif self.app.client_manager.auth_ref:
-            # Get the project from the current auth
-            project = self.app.client_manager.auth_ref
-            project_id = project.project_id
-            project_name = project.project_name
-        else:
-            project = None
-            project_id = None
-            project_name = None
-        project_info = {}
-        project_info['id'] = project_id
-        project_info['name'] = project_name
-        return project_info
-
-    def get_compute_volume_quota(self, client, parsed_args):
-        try:
-            if parsed_args.quota_class:
-                quota = client.quota_classes.get(parsed_args.project)
-            else:
-                project_info = self._get_project(parsed_args)
-                project = project_info['id']
-                if parsed_args.default:
-                    quota = client.quotas.defaults(project)
-                else:
-                    quota = client.quotas.get(project)
-        except Exception as e:
-            if type(e).__name__ == 'EndpointNotFound':
-                return {}
-            else:
-                raise
-        return quota._info
-
-    def get_network_quota(self, parsed_args):
-        if parsed_args.quota_class:
-            return {}
-        if self.app.client_manager.is_network_endpoint_enabled():
-            project_info = self._get_project(parsed_args)
-            project = project_info['id']
-            client = self.app.client_manager.network
-            if parsed_args.default:
-                network_quota = client.get_quota_default(project)
-            else:
-                network_quota = client.get_quota(project)
-            return network_quota
-        else:
-            return {}
-
     def take_action(self, parsed_args):
 
         compute_client = self.app.client_manager.compute
@@ -504,10 +607,10 @@ class ShowQuota(command.ShowOne):
         #                does not exist. If this is determined to be the
         #                intended behaviour of the API we will validate
         #                the argument with Identity ourselves later.
-        compute_quota_info = self.get_compute_volume_quota(compute_client,
-                                                           parsed_args)
-        volume_quota_info = self.get_compute_volume_quota(volume_client,
-                                                          parsed_args)
+        compute_quota_info = self.get_compute_quota(compute_client,
+                                                    parsed_args)
+        volume_quota_info = self.get_volume_quota(volume_client,
+                                                  parsed_args)
         network_quota_info = self.get_network_quota(parsed_args)
         # NOTE(reedip): Remove the below check once requirement for
         #               Openstack SDK is fixed to version 0.9.12 and above
diff --git a/openstackclient/tests/functional/common/test_quota.py b/openstackclient/tests/functional/common/test_quota.py
index 76c69a4d03..859422812b 100644
--- a/openstackclient/tests/functional/common/test_quota.py
+++ b/openstackclient/tests/functional/common/test_quota.py
@@ -31,6 +31,38 @@ class QuotaTests(base.TestCase):
         cls.PROJECT_NAME =\
             cls.get_openstack_configuration_value('auth.project_name')
 
+    def test_quota_list_details_compute(self):
+        expected_headers = ["Resource", "In Use", "Reserved", "Limit"]
+        cmd_output = json.loads(self.openstack(
+            'quota list -f json --detail --compute'
+        ))
+        self.assertIsNotNone(cmd_output)
+        resources = []
+        for row in cmd_output:
+            row_headers = [str(r) for r in row.keys()]
+            self.assertEqual(sorted(expected_headers), sorted(row_headers))
+            resources.append(row['Resource'])
+        # Ensure that returned quota is compute quota
+        self.assertIn("instances", resources)
+        # and that there is no network quota here
+        self.assertNotIn("networks", resources)
+
+    def test_quota_list_details_network(self):
+        expected_headers = ["Resource", "In Use", "Reserved", "Limit"]
+        cmd_output = json.loads(self.openstack(
+            'quota list -f json --detail --network'
+        ))
+        self.assertIsNotNone(cmd_output)
+        resources = []
+        for row in cmd_output:
+            row_headers = [str(r) for r in row.keys()]
+            self.assertEqual(sorted(expected_headers), sorted(row_headers))
+            resources.append(row['Resource'])
+        # Ensure that returned quota is network quota
+        self.assertIn("networks", resources)
+        # and that there is no compute quota here
+        self.assertNotIn("instances", resources)
+
     def test_quota_list_network_option(self):
         if not self.haz_network:
             self.skipTest("No Network service present")
diff --git a/openstackclient/tests/unit/common/test_quota.py b/openstackclient/tests/unit/common/test_quota.py
index 1a3da31d78..4f9e321b92 100644
--- a/openstackclient/tests/unit/common/test_quota.py
+++ b/openstackclient/tests/unit/common/test_quota.py
@@ -197,6 +197,85 @@ class TestQuotaList(TestQuota):
 
         self.cmd = quota.ListQuota(self.app, None)
 
+    @staticmethod
+    def _get_detailed_reference_data(quota):
+        reference_data = []
+        for name, values in quota.to_dict().items():
+            if type(values) is dict:
+                if 'used' in values:
+                    # For network quota it's "used" key instead of "in_use"
+                    in_use = values['used']
+                else:
+                    in_use = values['in_use']
+                resource_values = [
+                    in_use,
+                    values['reserved'],
+                    values['limit']]
+                reference_data.append(tuple([name] + resource_values))
+        return reference_data
+
+    def test_quota_list_details_compute(self):
+        detailed_quota = (
+            compute_fakes.FakeQuota.create_one_comp_detailed_quota())
+
+        detailed_column_header = (
+            'Resource',
+            'In Use',
+            'Reserved',
+            'Limit',
+        )
+        detailed_reference_data = (
+            self._get_detailed_reference_data(detailed_quota))
+
+        self.compute.quotas.get = mock.Mock(return_value=detailed_quota)
+
+        arglist = [
+            '--detail', '--compute',
+        ]
+        verifylist = [
+            ('detail', True),
+            ('compute', True),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+        ret_quotas = list(data)
+
+        self.assertEqual(detailed_column_header, columns)
+        self.assertEqual(
+            sorted(detailed_reference_data), sorted(ret_quotas))
+
+    def test_quota_list_details_network(self):
+        detailed_quota = (
+            network_fakes.FakeQuota.create_one_net_detailed_quota())
+
+        detailed_column_header = (
+            'Resource',
+            'In Use',
+            'Reserved',
+            'Limit',
+        )
+        detailed_reference_data = (
+            self._get_detailed_reference_data(detailed_quota))
+
+        self.network.get_quota = mock.Mock(return_value=detailed_quota)
+
+        arglist = [
+            '--detail', '--network',
+        ]
+        verifylist = [
+            ('detail', True),
+            ('network', True),
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        columns, data = self.cmd.take_action(parsed_args)
+        ret_quotas = list(data)
+
+        self.assertEqual(detailed_column_header, columns)
+        self.assertEqual(
+            sorted(detailed_reference_data), sorted(ret_quotas))
+
     def test_quota_list_compute(self):
         # Two projects with non-default quotas
         self.compute.quotas.get = mock.Mock(
@@ -827,13 +906,13 @@ class TestQuotaShow(TestQuota):
         self.cmd.take_action(parsed_args)
 
         self.compute_quotas_mock.get.assert_called_once_with(
-            self.projects[0].id,
+            self.projects[0].id, detail=False
         )
         self.volume_quotas_mock.get.assert_called_once_with(
             self.projects[0].id,
         )
         self.network.get_quota.assert_called_once_with(
-            self.projects[0].id,
+            self.projects[0].id, details=False
         )
         self.assertNotCalled(self.network.get_quota_default)
 
@@ -889,12 +968,12 @@ class TestQuotaShow(TestQuota):
         self.cmd.take_action(parsed_args)
 
         self.compute_quotas_mock.get.assert_called_once_with(
-            identity_fakes.project_id,
+            identity_fakes.project_id, detail=False
         )
         self.volume_quotas_mock.get.assert_called_once_with(
             identity_fakes.project_id,
         )
         self.network.get_quota.assert_called_once_with(
-            identity_fakes.project_id,
+            identity_fakes.project_id, details=False
         )
         self.assertNotCalled(self.network.get_quota_default)
diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py
index 38f4ff67f1..ee7d49831f 100644
--- a/openstackclient/tests/unit/compute/v2/fakes.py
+++ b/openstackclient/tests/unit/compute/v2/fakes.py
@@ -1401,6 +1401,38 @@ class FakeQuota(object):
 
         return quota
 
+    @staticmethod
+    def create_one_comp_detailed_quota(attrs=None):
+        """Create one quota"""
+
+        attrs = attrs or {}
+
+        quota_attrs = {
+            'id': 'project-id-' + uuid.uuid4().hex,
+            'cores': {'reserved': 0, 'in_use': 0, 'limit': 20},
+            'fixed_ips': {'reserved': 0, 'in_use': 0, 'limit': 30},
+            'injected_files': {'reserved': 0, 'in_use': 0, 'limit': 100},
+            'injected_file_content_bytes': {
+                'reserved': 0, 'in_use': 0, 'limit': 10240},
+            'injected_file_path_bytes': {
+                'reserved': 0, 'in_use': 0, 'limit': 255},
+            'instances': {'reserved': 0, 'in_use': 0, 'limit': 50},
+            'key_pairs': {'reserved': 0, 'in_use': 0, 'limit': 20},
+            'metadata_items': {'reserved': 0, 'in_use': 0, 'limit': 10},
+            'ram': {'reserved': 0, 'in_use': 0, 'limit': 51200},
+            'server_groups': {'reserved': 0, 'in_use': 0, 'limit': 10},
+            'server_group_members': {'reserved': 0, 'in_use': 0, 'limit': 10}
+        }
+
+        quota_attrs.update(attrs)
+        quota = fakes.FakeResource(
+            info=copy.deepcopy(quota_attrs),
+            loaded=True)
+
+        quota.project_id = quota_attrs['id']
+
+        return quota
+
 
 class FakeLimits(object):
     """Fake limits"""
diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py
index 28e92d1196..ee0919fdd5 100644
--- a/openstackclient/tests/unit/network/v2/fakes.py
+++ b/openstackclient/tests/unit/network/v2/fakes.py
@@ -1700,3 +1700,26 @@ class FakeQuota(object):
             info=copy.deepcopy(quota_attrs),
             loaded=True)
         return quota
+
+    @staticmethod
+    def create_one_net_detailed_quota(attrs=None):
+        """Create one quota"""
+        attrs = attrs or {}
+
+        quota_attrs = {
+            'floating_ips': {'used': 0, 'reserved': 0, 'limit': 20},
+            'networks': {'used': 0, 'reserved': 0, 'limit': 25},
+            'ports': {'used': 0, 'reserved': 0, 'limit': 11},
+            'rbac_policies': {'used': 0, 'reserved': 0, 'limit': 15},
+            'routers': {'used': 0, 'reserved': 0, 'limit': 40},
+            'security_groups': {'used': 0, 'reserved': 0, 'limit': 10},
+            'security_group_rules': {'used': 0, 'reserved': 0, 'limit': 100},
+            'subnets': {'used': 0, 'reserved': 0, 'limit': 20},
+            'subnet_pools': {'used': 0, 'reserved': 0, 'limit': 30}}
+
+        quota_attrs.update(attrs)
+
+        quota = fakes.FakeResource(
+            info=copy.deepcopy(quota_attrs),
+            loaded=True)
+        return quota
diff --git a/releasenotes/notes/list-detailed-quota-informations-1755129e1c68a252.yaml b/releasenotes/notes/list-detailed-quota-informations-1755129e1c68a252.yaml
new file mode 100644
index 0000000000..7dbe202cdd
--- /dev/null
+++ b/releasenotes/notes/list-detailed-quota-informations-1755129e1c68a252.yaml
@@ -0,0 +1,6 @@
+---
+features:
+  - |
+    Add support for list detailed ``quota`` usage for project.
+    This can be done by passing ``--detail`` parameter to `quota list` command.
+    [Bug `1716043 <https://bugs.launchpad.net/neutron/+bug/1716043>`_]