diff --git a/openstackclient/compute/v2/server.py b/openstackclient/compute/v2/server.py
index 33545a74e8..59fc4b7d44 100644
--- a/openstackclient/compute/v2/server.py
+++ b/openstackclient/compute/v2/server.py
@@ -4131,25 +4131,54 @@ class UnshelveServer(command.Command):
                    'SHELVED_OFFLOADED server (supported by '
                    '--os-compute-api-version 2.77 or above)'),
         )
+        parser.add_argument(
+            '--wait',
+            action='store_true',
+            default=False,
+            help=_('Wait for unshelve operation to complete'),
+        )
         return parser
 
     def take_action(self, parsed_args):
+
+        def _show_progress(progress):
+            if progress:
+                self.app.stdout.write('\rProgress: %s' % progress)
+                self.app.stdout.flush()
+
         compute_client = self.app.client_manager.compute
-        support_az = compute_client.api_version >= api_versions.APIVersion(
-            '2.77')
-        if not support_az and parsed_args.availability_zone:
-            msg = _("--os-compute-api-version 2.77 or greater is required "
-                    "to support the '--availability-zone' option.")
-            raise exceptions.CommandError(msg)
+        kwargs = {}
+
+        if parsed_args.availability_zone:
+            if compute_client.api_version < api_versions.APIVersion('2.77'):
+                msg = _(
+                    '--os-compute-api-version 2.77 or greater is required '
+                    'to support the --availability-zone option'
+                )
+                raise exceptions.CommandError(msg)
+
+            kwargs['availability_zone'] = parsed_args.availability_zone
 
         for server in parsed_args.server:
-            if support_az:
-                utils.find_resource(
-                    compute_client.servers,
-                    server
-                ).unshelve(availability_zone=parsed_args.availability_zone)
-            else:
-                utils.find_resource(
-                    compute_client.servers,
-                    server,
-                ).unshelve()
+            server_obj = utils.find_resource(
+                compute_client.servers,
+                server,
+            )
+
+            if server_obj.status.lower() not in (
+                'shelved', 'shelved_offloaded',
+            ):
+                continue
+
+            server_obj.unshelve(**kwargs)
+
+            if parsed_args.wait:
+                if not utils.wait_for_status(
+                    compute_client.servers.get, server_obj.id,
+                    success_status=('active', 'shutoff'),
+                    callback=_show_progress,
+                ):
+                    LOG.error(_('Error unshelving server %s'), server_obj.id)
+                    self.app.stdout.write(
+                        _('Error unshelving server: %s\n') % server_obj.id)
+                    raise SystemExit
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index 9ad6d15508..2c0cadfc88 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -6969,6 +6969,9 @@ class TestServerUnshelve(TestServer):
         self.methods = {
             'unshelve': None,
         }
+        self.attrs = {
+            'status': 'SHELVED',
+        }
 
     def test_unshelve_one_server(self):
         self.run_method_with_servers('unshelve', 1)
@@ -6976,8 +6979,34 @@ class TestServerUnshelve(TestServer):
     def test_unshelve_multi_servers(self):
         self.run_method_with_servers('unshelve', 3)
 
-    def test_unshelve_server_with_specified_az(self):
-        server = compute_fakes.FakeServer.create_one_server()
+    def test_unshelve_with_specified_az(self):
+        self.app.client_manager.compute.api_version = \
+            api_versions.APIVersion('2.77')
+
+        server = compute_fakes.FakeServer.create_one_server(
+            attrs=self.attrs, methods=self.methods)
+        self.servers_mock.get.return_value = server
+        arglist = [
+            '--availability-zone', "foo-az",
+            server.id,
+        ]
+        verifylist = [
+            ('availability_zone', "foo-az"),
+            ('server', [server.id])
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        self.cmd.take_action(parsed_args)
+
+        self.servers_mock.get.assert_called_with(server.id)
+        server.unshelve.assert_called_with(availability_zone="foo-az")
+
+    def test_unshelve_with_specified_az_pre_v277(self):
+        self.app.client_manager.compute.api_version = \
+            api_versions.APIVersion('2.76')
+
+        server = compute_fakes.FakeServer.create_one_server(
+            attrs=self.attrs, methods=self.methods)
         arglist = [
             server.id,
             '--availability-zone', "foo-az",
@@ -6987,44 +7016,37 @@ class TestServerUnshelve(TestServer):
             ('server', [server.id])
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
-        ex = self.assertRaises(exceptions.CommandError,
-                               self.cmd.take_action,
-                               parsed_args)
+        ex = self.assertRaises(
+            exceptions.CommandError,
+            self.cmd.take_action,
+            parsed_args)
         self.assertIn(
             '--os-compute-api-version 2.77 or greater is required', str(ex))
 
+    @mock.patch.object(common_utils, 'wait_for_status', return_value=True)
+    def test_unshelve_with_wait(self, mock_wait_for_status):
+        server = compute_fakes.FakeServer.create_one_server(
+            attrs=self.attrs, methods=self.methods)
+        self.servers_mock.get.return_value = server
 
-class TestServerUnshelveV277(TestServerUnshelve):
-
-    def setUp(self):
-        super(TestServerUnshelveV277, self).setUp()
-
-        self.server = compute_fakes.FakeServer.create_one_server(
-            methods=self.methods)
-
-        # This is the return value for utils.find_resource()
-        self.servers_mock.get.return_value = self.server
-
-        # Get the command object to test
-        self.cmd = server.UnshelveServer(self.app, None)
-
-    def test_specified_az_to_unshelve_with_v277(self):
-        self.app.client_manager.compute.api_version = api_versions.APIVersion(
-            '2.77')
-
-        arglist = [
-            '--availability-zone', "foo-az",
-            self.server.id,
-        ]
+        arglist = ['--wait', server.name]
         verifylist = [
-            ('availability_zone', "foo-az"),
-            ('server', [self.server.id])
+            ('server', [server.name]),
+            ('wait', True),
         ]
         parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 
-        self.cmd.take_action(parsed_args)
-        self.servers_mock.get.assert_called_with(self.server.id)
-        self.server.unshelve.assert_called_with(availability_zone="foo-az")
+        result = self.cmd.take_action(parsed_args)
+        self.assertIsNone(result)
+
+        self.servers_mock.get.assert_called_once_with(server.name)
+        server.unshelve.assert_called_once_with()
+        mock_wait_for_status.assert_called_once_with(
+            self.servers_mock.get,
+            server.id,
+            callback=mock.ANY,
+            success_status=('active', 'shutoff'),
+        )
 
 
 class TestServerGeneral(TestServer):
diff --git a/releasenotes/notes/add-shelve-offload-wait-d0a5c8ba92586f72.yaml b/releasenotes/notes/add-shelve-offload-wait-d0a5c8ba92586f72.yaml
index ddd3293191..750abd6af1 100644
--- a/releasenotes/notes/add-shelve-offload-wait-d0a5c8ba92586f72.yaml
+++ b/releasenotes/notes/add-shelve-offload-wait-d0a5c8ba92586f72.yaml
@@ -6,3 +6,5 @@ features:
     server in environments where automatic offloading is not configured, while
     ``--wait`` allows users to wait for the shelve and/or shelve offload
     operations to complete.
+  - |
+    Add support ``--wait`` option for ``server shelve``.