As technology scales, transient faults have emerged as a key challenge for reliable embedded system design. This paper proposes a design methodology that incorporates reliability into hardware-software co-design paradigm for embedded systems. We introduce an allocation and scheduling algorithm that efficiently handles conditional execution in multi-rate embedded systems, and selectively duplicates critical tasks to detect or correct transient errors, such that the reliability of the system is improved. Two methods are proposed to insert duplicated tasks into the schedule. The improved reliability is achieved by utilizing the otherwise idle computation resources and taking advantage of the overlapping schedule for mutually exclusive tasks in the conditional task graph, such that it incurs no resource or performance penalty.