diff --git a/src/content/docs/components/index.mdx b/src/content/docs/components/index.mdx
index 0e87d16609b..8138f580df2 100644
--- a/src/content/docs/components/index.mdx
+++ b/src/content/docs/components/index.mdx
@@ -1087,6 +1087,7 @@ Used for creating infrared (IR) remote control transmitters and/or receivers.
## Water Heater Components
diff --git a/src/content/docs/components/valve/time_based.mdx b/src/content/docs/components/valve/time_based.mdx
new file mode 100644
index 00000000000..e59fc90a51c
--- /dev/null
+++ b/src/content/docs/components/valve/time_based.mdx
@@ -0,0 +1,98 @@
+---
+description: "Instructions for setting up time-based valves in ESPHome."
+title: "Time Based Valve"
+---
+
+import { Image } from 'astro:assets';
+import valveUiImg from './images/valve-ui.png';
+import APIRef from '@components/APIRef.astro';
+
+The `time_based` valve platform allows you to create valves with position control that do not
+have any position feedback. The state of the valve is thus always an assumed one, the current
+position is approximated with the time the valve has been moving in a direction. The state
+of the valve can be restored at node reboot.
+
+
+
+```yaml
+# Example configuration entry
+valve:
+ - platform: time_based
+ name: "Time-Based Valve"
+
+ open_action:
+ - switch.turn_on: open_valve_switch
+ open_duration: 2.1min
+
+ close_action:
+ - switch.turn_on: close_valve_switch
+ close_duration: 2min
+
+ stop_action:
+ - switch.turn_off: open_valve_switch
+ - switch.turn_off: close_valve_switch
+```
+
+## Configuration variables
+
+- **open_action** (**Required**, [Action](/automations/actions#all-actions)): The action that should
+ be performed when the remote requests the valve to be opened.
+
+- **open_duration** (**Required**, [Time](/guides/configuration-types#time)): The amount of time it takes the valve
+ to open up from the fully-closed state.
+
+- **close_action** (**Required**, [Action](/automations/actions#all-actions)): The action that should
+ be performed when the remote requests the valve to be closed.
+
+- **close_duration** (**Required**, [Time](/guides/configuration-types#time)): The amount of time it takes the valve
+ to close from the fully-open state.
+
+- **stop_action** (**Required**, [Action](/automations/actions#all-actions)): The action that should
+ be performed to stop the valve when the remote requests the valve to be stopped or
+ when the valve has been opening/closing for the given durations.
+
+- **has_built_in_endstop** (*Optional*, boolean): Indicates that the valve has built in end stop
+ detectors. In this configuration the `stop_action` is not performed when the open or close
+ time is completed and if the valve is commanded to open or close the corresponding actions
+ will be performed without checking current state. Defaults to `false`.
+
+- **manual_control** (*Optional*, boolean): For valves with manual external controls. With this
+ configuration if the valve is commanded to open or close the corresponding actions will be
+ performed even if the current state fully open or fully closed matches desired state, then
+ `stop_action` will be called after the full duration of the action elapses.
+ The current state will then be relearned upon completion.
+ It's recommended to set `assumed_state` to true so the valve control buttons aren't disabled
+ in the interface. Defaults to `false`.
+
+- **assumed_state** (*Optional*, boolean): Whether the true state of the valve is not known.
+ This will make the Home Assistant frontend show buttons for both OPEN and CLOSE actions, instead
+ of hiding or disabling one of them. Defaults to `true`.
+
+- All other options from [Valve](/components/valve#config-valve).
+
+> [!NOTE]
+> The stop button on the UI is always enabled even when the valve is stopped and each press
+> on the button will cause the `stop_action` to be performed.
+
+## Handle stop_action
+
+For some valve controllers, separate switches for OPEN and CLOSE action are used while a stop is issued when sending a counter command.
+This can be handled at the **stop_action** by using the following lambda function:
+
+```yaml
+stop_action:
+ - lambda: !lambda |-
+ if (id(valve).get_last_operation() == ValveOperation::VALVE_OPERATION_OPENING) {
+ // Valve is currently opening
+ id(valve_button_close).press();
+ } else if (id(valve).get_last_operation() == ValveOperation::VALVE_OPERATION_CLOSING) {
+ // Valve is currently closing
+ id(valve_button_open).press();
+ }
+```
+
+## See Also
+
+- [Valve Component](/components/valve/)
+- [Automation](/automations)
+-