diff --git a/lib/ansible/modules/cloud/hcloud/hcloud_server.py b/lib/ansible/modules/cloud/hcloud/hcloud_server.py
index 658dfed8be8..2fc9b7ee096 100644
--- a/lib/ansible/modules/cloud/hcloud/hcloud_server.py
+++ b/lib/ansible/modules/cloud/hcloud/hcloud_server.py
@@ -89,6 +89,10 @@ options:
             - User Data to be passed to the server on creation.
             - Only used if server does not exists.
         type: str
+    labels:
+        description:
+            - User-defined labels (key-value pairs).
+        type: dict
     state:
         description:
             - State of the server.
@@ -224,6 +228,7 @@ class AnsibleHcloudServer(Hcloud):
             ),
             "image": self.client.images.get_by_name(self.module.params.get("image")),
             "user_data": self.module.params.get("user_data"),
+            "labels": self.module.params.get("labels"),
         }
 
         if self.module.params.get("ssh_keys") is not None:
@@ -268,6 +273,12 @@ class AnsibleHcloudServer(Hcloud):
                 self.hcloud_server.disable_backup().wait_until_finished()
             self._mark_as_changed()
 
+        labels = self.module.params.get("labels")
+        if labels is not None:
+            if not self.module.check_mode:
+                self.hcloud_server.update(labels=labels)
+            self._mark_as_changed()
+
         server_type = self.module.params.get("server_type")
         if server_type is not None and self.hcloud_server.server_type.name != server_type:
             previous_server_status = self.hcloud_server.status
@@ -339,6 +350,7 @@ class AnsibleHcloudServer(Hcloud):
                 user_data={"type": "str"},
                 ssh_keys={"type": "list"},
                 volumes={"type": "list"},
+                labels={"type": "dict"},
                 backups={"type": "bool", "default": False},
                 upgrade_disk={"type": "bool", "default": False},
                 force_upgrade={"type": "bool", "default": False},
diff --git a/test/integration/targets/hcloud_server/tasks/main.yml b/test/integration/targets/hcloud_server/tasks/main.yml
index c53c0035d30..5a9722b3a5c 100644
--- a/test/integration/targets/hcloud_server/tasks/main.yml
+++ b/test/integration/targets/hcloud_server/tasks/main.yml
@@ -273,3 +273,51 @@
   assert:
     that:
     - result is success
+
+- name: test create server with labels
+  hcloud_server:
+    name: "{{ hcloud_server_name}}"
+    server_type: cx11
+    image: "ubuntu-18.04"
+    ssh_keys:
+      - ci@ansible.hetzner.cloud
+    labels:
+      key: value
+      mylabel: 123
+    state: started
+  register: main_server
+- name: verify create server with labels
+  assert:
+    that:
+      - main_server is changed
+      - main_server.hcloud_server.labels.key == "value"
+      - main_server.hcloud_server.labels.mylabel == 123
+
+- name: test update server with labels
+  hcloud_server:
+    name: "{{ hcloud_server_name}}"
+    server_type: cx11
+    image: "ubuntu-18.04"
+    ssh_keys:
+      - ci@ansible.hetzner.cloud
+    labels:
+      key: other
+      mylabel: 123
+    state: started
+  register: main_server
+- name: verify update server with labels
+  assert:
+    that:
+      - main_server is changed
+      - main_server.hcloud_server.labels.key == "other"
+      - main_server.hcloud_server.labels.mylabel == 123
+
+- name: cleanup with labels
+  hcloud_server:
+    name: "{{ hcloud_server_name }}"
+    state: absent
+  register: result
+- name: verify cleanup
+  assert:
+    that:
+    - result is success