diff --git a/libpod/define/annotations.go b/libpod/define/annotations.go
index 50bc52571a..a70f83f785 100644
--- a/libpod/define/annotations.go
+++ b/libpod/define/annotations.go
@@ -140,6 +140,10 @@ const (
 	// of the init container.
 	InitContainerType = "io.podman.annotations.init.container.type"
 
+	// UlimitAnnotation is used by kube play when playing a kube yaml to specify the ulimits
+	// of the container
+	UlimitAnnotation = "io.podman.annotations.ulimit"
+
 	// MaxKubeAnnotation is the max length of annotations allowed by Kubernetes.
 	MaxKubeAnnotation = 63
 )
diff --git a/libpod/kube.go b/libpod/kube.go
index 240ab4e322..b5ff66fd44 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -531,6 +531,24 @@ func simplePodWithV1Containers(ctx context.Context, ctrs []*Container) (*v1.Pod,
 			}
 		}
 
+		if ctr.config.Spec.Process != nil {
+			var ulimitArr []string
+			defaultUlimits := util.DefaultContainerConfig().Ulimits()
+			for _, ulimit := range ctr.config.Spec.Process.Rlimits {
+				finalUlimit := strings.ToLower(strings.ReplaceAll(ulimit.Type, "RLIMIT_", "")) + "=" + strconv.Itoa(int(ulimit.Soft)) + ":" + strconv.Itoa(int(ulimit.Hard))
+				// compare ulimit with default list so we don't add it twice
+				if cutil.StringInSlice(finalUlimit, defaultUlimits) {
+					continue
+				}
+
+				ulimitArr = append(ulimitArr, finalUlimit)
+			}
+
+			if len(ulimitArr) > 0 {
+				kubeAnnotations[define.UlimitAnnotation] = strings.Join(ulimitArr, ",")
+			}
+		}
+
 		if !ctr.HostNetwork() {
 			hostNetwork = false
 		}
diff --git a/pkg/specgen/generate/kube/kube.go b/pkg/specgen/generate/kube/kube.go
index 4a3d6648e8..09fe5fc7c6 100644
--- a/pkg/specgen/generate/kube/kube.go
+++ b/pkg/specgen/generate/kube/kube.go
@@ -273,6 +273,18 @@ func ToSpecGen(ctx context.Context, opts *CtrSpecGenOptions) (*specgen.SpecGener
 		s.ResourceLimits.Memory.Reservation = &memoryRes
 	}
 
+	ulimitVal, ok := opts.Annotations[define.UlimitAnnotation]
+	if ok {
+		ulimits := strings.Split(ulimitVal, ",")
+		for _, ul := range ulimits {
+			parsed, err := units.ParseUlimit(ul)
+			if err != nil {
+				return nil, err
+			}
+			s.Rlimits = append(s.Rlimits, spec.POSIXRlimit{Type: parsed.Name, Soft: uint64(parsed.Soft), Hard: uint64(parsed.Hard)})
+		}
+	}
+
 	// TODO: We don't understand why specgen does not take of this, but
 	// integration tests clearly pointed out that it was required.
 	imageData, err := opts.Image.Inspect(ctx, nil)
diff --git a/test/e2e/generate_kube_test.go b/test/e2e/generate_kube_test.go
index 0f14b2985c..00b68ee551 100644
--- a/test/e2e/generate_kube_test.go
+++ b/test/e2e/generate_kube_test.go
@@ -72,7 +72,6 @@ var _ = Describe("Podman kube generate", func() {
 		Expect(pod.Spec.Containers[0].SecurityContext).To(BeNil())
 		Expect(pod.Spec.Containers[0].Env).To(BeNil())
 		Expect(pod).To(HaveField("Name", "top-pod"))
-		Expect(pod.Annotations).To(HaveLen(0))
 
 		numContainers := 0
 		for range pod.Spec.Containers {
@@ -1330,4 +1329,40 @@ USER test1`
 
 		Expect(pod.Spec.Volumes[0].Secret).To(BeNil())
 	})
+
+	It("podman generate & play kube with --ulimit set", func() {
+		ctrName := "ulimit-ctr"
+		ctrNameInKubePod := ctrName + "-pod-" + ctrName
+		session1 := podmanTest.Podman([]string{"run", "-d", "--name", ctrName, "--ulimit", "nofile=1231:3123", ALPINE, "sleep", "1000"})
+		session1.WaitWithDefaultTimeout()
+		Expect(session1).Should(Exit(0))
+
+		outputFile := filepath.Join(podmanTest.RunRoot, "pod.yaml")
+		kube := podmanTest.Podman([]string{"kube", "generate", ctrName, "-f", outputFile})
+		kube.WaitWithDefaultTimeout()
+		Expect(kube).Should(Exit(0))
+
+		b, err := os.ReadFile(outputFile)
+		Expect(err).ShouldNot(HaveOccurred())
+		pod := new(v1.Pod)
+		err = yaml.Unmarshal(b, pod)
+		Expect(err).ToNot(HaveOccurred())
+		Expect(pod.Annotations).To(HaveKey(define.UlimitAnnotation))
+		Expect(pod.Annotations[define.UlimitAnnotation]).To(ContainSubstring("nofile=1231:3123"))
+
+		rm := podmanTest.Podman([]string{"pod", "rm", "-t", "0", "-f", ctrName})
+		rm.WaitWithDefaultTimeout()
+		Expect(rm).Should(Exit(0))
+
+		play := podmanTest.Podman([]string{"kube", "play", outputFile})
+		play.WaitWithDefaultTimeout()
+		Expect(play).Should(Exit(0))
+
+		inspect := podmanTest.Podman([]string{"inspect", ctrNameInKubePod})
+		inspect.WaitWithDefaultTimeout()
+		Expect(inspect).Should(Exit(0))
+		Expect(inspect.OutputToString()).To(ContainSubstring("RLIMIT_NOFILE"))
+		Expect(inspect.OutputToString()).To(ContainSubstring("1231"))
+		Expect(inspect.OutputToString()).To(ContainSubstring("3123"))
+	})
 })