diff --git a/requests.http b/requests.http
index 7e78e46efff37a1bdc7147e29b6198566e22b12d..88e0fc53498af6a2dd287adb7b724f9f044220a1 100644
--- a/requests.http
+++ b/requests.http
@@ -25,3 +25,18 @@ content-type: application/json
   "email": "lukas.karsch@gmx.de",
   "password": "myPassword123"
 }
+
+### Get all plants from wishlist
+GET http://localhost:8080/api/v1/wishlist
+
+### Get amount of plants in wishlist
+GET http://localhost:8080/api/v1/wishlist/count
+
+### Add plant to wishlist
+POST http://localhost:8080/api/v1/wishlist/add/1
+
+### Remove plant from wishlist
+DELETE http://localhost:8080/api/v1/wishlist/remove/1
+
+### Remove all plants from wishlist
+DELETE http://localhost:8080/api/v1/wishlist/remove/all
\ No newline at end of file
diff --git a/src/main/java/hdm/mi/growbros/controllers/WishListController.java b/src/main/java/hdm/mi/growbros/controllers/WishListController.java
new file mode 100644
index 0000000000000000000000000000000000000000..54f406664c88b466a67f1b1936bfb821def8c055
--- /dev/null
+++ b/src/main/java/hdm/mi/growbros/controllers/WishListController.java
@@ -0,0 +1,53 @@
+package hdm.mi.growbros.controllers;
+
+import hdm.mi.growbros.models.plant.Plant;
+import hdm.mi.growbros.models.user.User;
+import hdm.mi.growbros.service.WishListService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.annotation.AuthenticationPrincipal;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Collection;
+
+@RestController
+@CrossOrigin
+@RequestMapping("/api/v1/wishlist")
+@RequiredArgsConstructor
+public class WishListController {
+
+    private final WishListService wishListService;
+
+    @GetMapping
+    public Collection<Plant> getAllPlantsInWishList(@RequestParam(value = "sort", required = false) String sort,
+                                                    @AuthenticationPrincipal User user) {
+        return wishListService.getWishedPlants(user, sort);
+    }
+
+    @GetMapping("/count")
+    public int getWishListSize(
+            @AuthenticationPrincipal User user) {
+        return wishListService.countByUser(user);
+    }
+
+
+    @PostMapping("/add/{plantId}")
+    public ResponseEntity<Integer> addPlantToWishlist(@PathVariable Long plantId,
+                                                      @AuthenticationPrincipal User user) {
+        wishListService.addPlantToWishList(plantId, user);
+        return ResponseEntity.status(201).build();
+    }
+
+    @DeleteMapping("/remove/{entryId}")
+    @ResponseStatus(HttpStatus.NO_CONTENT)
+    public void removePlantFromWishlist(@PathVariable Long entryId,
+                                        @AuthenticationPrincipal User user) {
+        wishListService.removeFromWishList(entryId, user);
+    }
+
+    @DeleteMapping("/remove/all")
+    public int removeAllPlantsFromWishlist(@AuthenticationPrincipal User user) {
+        return wishListService.clearWishList(user);
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/hdm/mi/growbros/models/WishListEntry.java b/src/main/java/hdm/mi/growbros/models/WishListEntry.java
new file mode 100644
index 0000000000000000000000000000000000000000..90e8ae4e6a7b9d25dbc7788e8968c407067610d8
--- /dev/null
+++ b/src/main/java/hdm/mi/growbros/models/WishListEntry.java
@@ -0,0 +1,33 @@
+package hdm.mi.growbros.models;
+
+import hdm.mi.growbros.models.plant.Plant;
+import hdm.mi.growbros.models.user.User;
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+
+import java.util.Date;
+
+@Entity
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class WishListEntry {
+
+    @ManyToOne
+    @CreatedBy
+    private User user;
+
+    @ManyToOne
+    private Plant plant;
+
+    @CreatedDate
+    private Date createdAt;
+
+    @Id
+    @GeneratedValue
+    private Long id;
+}
\ No newline at end of file
diff --git a/src/main/java/hdm/mi/growbros/repositories/WishListRepository.java b/src/main/java/hdm/mi/growbros/repositories/WishListRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..f1c8d560b25478583f2844f4643b697dac68565d
--- /dev/null
+++ b/src/main/java/hdm/mi/growbros/repositories/WishListRepository.java
@@ -0,0 +1,51 @@
+package hdm.mi.growbros.repositories;
+
+import hdm.mi.growbros.models.plant.Plant;
+import hdm.mi.growbros.models.WishListEntry;
+import hdm.mi.growbros.models.user.User;
+import org.springframework.data.domain.Sort;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+
+@Repository
+public interface WishListRepository extends JpaRepository<WishListEntry, Long> {
+
+    List<WishListEntry> findByUser(User user);
+
+    List<WishListEntry> findByUser(User user, Sort sort);
+
+    int countByUser(User user);
+
+    int deleteAllByUser(User user);
+
+    void deleteByIdAndUser(long entryId, User user);
+
+    @Query("""
+                SELECT ge FROM WishListEntry ge
+                WHERE ge.user = :user
+                ORDER BY
+                    CASE
+                        WHEN :week <= ge.plant.plantWeekStart
+                            THEN ABS(:week - ge.plant.plantWeekStart)
+                        ELSE ABS(52 + :week - ge.plant.plantWeekStart)
+                    END,
+                    ge.plant.name
+                ASC
+            """)
+    List<WishListEntry> findAllByNearestPlantingWeek(@Param("user") User user, @Param("week") int currentWeek);
+
+    @Query("""
+                SELECT ge FROM WishListEntry ge
+                WHERE ge.user = :user
+                AND ge.plant.plantWeekStart <= :week
+                AND ge.plant.plantWeekEnd >= :week
+            """)
+    List<WishListEntry> findByCurrentPlantingWeek(@Param("user") User user, @Param("week") int currentWeek);
+
+    boolean existsByUserAndPlant(User user, Plant plant);
+}
\ No newline at end of file
diff --git a/src/main/java/hdm/mi/growbros/service/WishListService.java b/src/main/java/hdm/mi/growbros/service/WishListService.java
new file mode 100644
index 0000000000000000000000000000000000000000..0d832d672cd617de3053b346178779ed0c847c68
--- /dev/null
+++ b/src/main/java/hdm/mi/growbros/service/WishListService.java
@@ -0,0 +1,90 @@
+package hdm.mi.growbros.service;
+
+import hdm.mi.growbros.exceptions.PlantNotFoundException;
+import hdm.mi.growbros.models.WishListEntry;
+import hdm.mi.growbros.models.plant.Plant;
+import hdm.mi.growbros.models.user.User;
+import hdm.mi.growbros.repositories.PlantRepository;
+import hdm.mi.growbros.repositories.WishListRepository;
+import hdm.mi.growbros.util.DateTimeUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.domain.Sort;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+
+
+@Service
+@RequiredArgsConstructor
+public class WishListService {
+
+    private final WishListRepository wishListRepository;
+    private final PlantRepository plantRepository;
+
+    public List<Plant> getWishedPlants(User user, String sort) {
+        if (sort == null) return getAllPlantsOrderedByName(user);
+        return switch (sort) {
+            case "createdAt" -> getAllPlantsOrderedByCreatedDate(user);
+            case "plantDate" -> getAllPlantsOrderedByNextPossiblePlantDate(user);
+            case "currentPlantable" -> getCurrentPlantablePlants(user);
+            default -> getAllPlantsOrderedByName(user);
+        };
+    }
+
+    public void addPlantToWishList(Long plantId, User user) {
+        Plant plant = plantRepository.findById(plantId).orElseThrow(() -> new PlantNotFoundException(plantId));
+
+        if (wishListRepository.existsByUserAndPlant(user, plant)) {
+            return;
+        }
+
+        WishListEntry wishListEntry = new WishListEntry();
+        wishListEntry.setPlant(plant);
+        wishListEntry.setUser(user);
+        wishListRepository.save(wishListEntry);
+    }
+
+    public void removeFromWishList(Long entryId, User user) {
+        wishListRepository.deleteByIdAndUser(entryId, user);
+    }
+
+    public int clearWishList(User user) {
+        return wishListRepository.deleteAllByUser(user);
+    }
+
+    private List<Plant> getAllPlantsOrderedByName(User user) {
+        return mapWishListEntriesToPlants(
+                wishListRepository.findByUser(user, Sort.by("plant.name"))
+        );
+    }
+
+    private List<Plant> getAllPlantsOrderedByCreatedDate(User user) {
+        return mapWishListEntriesToPlants(
+                wishListRepository.findByUser(user, Sort.by("createdAt"))
+        );
+    }
+
+    private List<Plant> getAllPlantsOrderedByNextPossiblePlantDate(User user) {
+        return mapWishListEntriesToPlants(
+                wishListRepository.findAllByNearestPlantingWeek(user, DateTimeUtils.getCurrentWeekForToday())
+        );
+    }
+
+    private List<Plant> getCurrentPlantablePlants(User user) {
+        return mapWishListEntriesToPlants(
+                wishListRepository.findByCurrentPlantingWeek(user, DateTimeUtils.getCurrentWeekForToday())
+        );
+    }
+
+    private List<Plant> mapWishListEntriesToPlants(Collection<WishListEntry> entries) {
+        return entries
+                .stream()
+                .map(WishListEntry::getPlant)
+                .toList();
+    }
+
+    public int countByUser(User user) {
+        return wishListRepository.countByUser(user);
+    }
+}
\ No newline at end of file