diff --git a/pkg/api/handlers/libpod/volumes.go b/pkg/api/handlers/libpod/volumes.go
index 3ba39b8606..ffdb305515 100644
--- a/pkg/api/handlers/libpod/volumes.go
+++ b/pkg/api/handlers/libpod/volumes.go
@@ -29,12 +29,13 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
 	}{
 		// override any golang type defaults
 	}
-	input := entities.VolumeCreateOptions{}
 	if err := decoder.Decode(&query, r.URL.Query()); err != nil {
 		utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError,
 			errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
 		return
 	}
+
+	input := entities.VolumeCreateOptions{}
 	// decode params from body
 	if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
 		utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()"))
@@ -47,9 +48,19 @@ func CreateVolume(w http.ResponseWriter, r *http.Request) {
 	if len(input.Driver) > 0 {
 		volumeOptions = append(volumeOptions, libpod.WithVolumeDriver(input.Driver))
 	}
-	if len(input.Label) > 0 {
-		volumeOptions = append(volumeOptions, libpod.WithVolumeLabels(input.Label))
+
+	// Label provided for compatibility.
+	labels := make(map[string]string, len(input.Label)+len(input.Labels))
+	for k, v := range input.Label {
+		labels[k] = v
 	}
+	for k, v := range input.Labels {
+		labels[k] = v
+	}
+	if len(labels) > 0 {
+		volumeOptions = append(volumeOptions, libpod.WithVolumeLabels(labels))
+	}
+
 	if len(input.Options) > 0 {
 		parsedOptions, err := parse.VolumeOptions(input.Options)
 		if err != nil {
diff --git a/pkg/domain/entities/volumes.go b/pkg/domain/entities/volumes.go
index 2ecfb4446f..9b2a170e2b 100644
--- a/pkg/domain/entities/volumes.go
+++ b/pkg/domain/entities/volumes.go
@@ -78,8 +78,10 @@ type VolumeCreateOptions struct {
 	Name string `schema:"name"`
 	// Volume driver to use
 	Driver string `schema:"driver"`
-	// User-defined key/value metadata.
+	// User-defined key/value metadata. Provided for compatibility
 	Label map[string]string `schema:"label"`
+	// User-defined key/value metadata. Preferred field, will override Label
+	Labels map[string]string `schema:"labels"`
 	// Mapping of driver options and values.
 	Options map[string]string `schema:"opts"`
 }
diff --git a/test/apiv2/python/rest_api/test_v2_0_0_volume.py b/test/apiv2/python/rest_api/test_v2_0_0_volume.py
index f5231e17c3..2156318b04 100644
--- a/test/apiv2/python/rest_api/test_v2_0_0_volume.py
+++ b/test/apiv2/python/rest_api/test_v2_0_0_volume.py
@@ -7,7 +7,7 @@ from .fixtures import APITestCase
 
 
 class VolumeTestCase(APITestCase):
-    def test_volume(self):
+    def test_volume_crud(self):
         name = f"Volume_{random.getrandbits(160):x}"
 
         ls = requests.get(self.podman_url + "/v1.40/volumes")
@@ -70,6 +70,71 @@ class VolumeTestCase(APITestCase):
         self.assertIn(name, payload["VolumesDeleted"])
         self.assertGreater(payload["SpaceReclaimed"], 0)
 
+    def test_volume_label(self):
+        name = f"Volume_{random.getrandbits(160):x}"
+        expected = {
+            "Production": "False",
+            "Database": "Foxbase",
+        }
+
+        create = requests.post(
+            self.podman_url + "/v4.0.0/libpod/volumes/create",
+            json={"name": name, "label": expected},
+        )
+        self.assertEqual(create.status_code, 201, create.text)
+
+        inspect = requests.get(self.podman_url + f"/v4.0.0/libpod/volumes/{name}/json")
+        self.assertEqual(inspect.status_code, 200, inspect.text)
+
+        volume = inspect.json()
+        self.assertIn("Labels", volume)
+        self.assertNotIn("Label", volume)
+        self.assertDictEqual(expected, volume["Labels"])
+
+    def test_volume_labels(self):
+        name = f"Volume_{random.getrandbits(160):x}"
+        expected = {
+            "Production": "False",
+            "Database": "Foxbase",
+        }
+
+        create = requests.post(
+            self.podman_url + "/v4.0.0/libpod/volumes/create",
+            json={"name": name, "labels": expected},
+        )
+        self.assertEqual(create.status_code, 201, create.text)
+
+        inspect = requests.get(self.podman_url + f"/v4.0.0/libpod/volumes/{name}/json")
+        self.assertEqual(inspect.status_code, 200, inspect.text)
+
+        volume = inspect.json()
+        self.assertIn("Labels", volume)
+        self.assertDictEqual(expected, volume["Labels"])
+
+    def test_volume_label_override(self):
+        name = f"Volume_{random.getrandbits(160):x}"
+        create = requests.post(
+            self.podman_url + "/v4.0.0/libpod/volumes/create",
+            json={
+                "Name": name,
+                "Label": {
+                    "Database": "dbase",
+                },
+                "Labels": {
+                    "Database": "sqlserver",
+                },
+            },
+        )
+        self.assertEqual(create.status_code, 201, create.text)
+
+        inspect = requests.get(self.podman_url + f"/v4.0.0/libpod/volumes/{name}/json")
+        self.assertEqual(inspect.status_code, 200, inspect.text)
+
+        volume = inspect.json()
+        self.assertIn("Labels", volume)
+        self.assertNotIn("Label", volume)
+        self.assertDictEqual({"Database": "sqlserver"}, volume["Labels"])
+
 
 if __name__ == "__main__":
     unittest.main()